MySQL基於時間點的恢復


MySQL基於時間點的恢復通常是拷貝一份binglogs,用mysqlbinlog來重放事務。但是,這個方式有很多的缺點,使得基於時間點的恢復很難。比如:

·需要確保對所有的binlogs執行單個mysqlbinlog命令,並通過管道傳遞給mysql客戶端。要不然,binlog.000001創建一個臨時表,binlog.000002需要該臨時表的時候去看不到該臨時表。每次執行mysql都會創建一個新的連接

shell> mysqlbinlog binlog.000001 | mysql -u root -p # Creates tmp table X
shell> mysqlbinlog binlog.000002 | mysql -u root -p # Uses tmp table X

正確的做法是:
shell> mysqlbinlog binlog.000001 binlog.000002 | mysql -u root -p
或者
mysqlbinlog –base64-output=decode -v binlog.000001 >> binlog.txt
mysqlbinlog –base64-output=decode -v binlog.000002 >> binlog.txt
mysql < binlog.txt

·必須要是原子操作。如果中途斷開,想知道是在哪個位置斷開就很難了,繼續執行基於時間點的恢復更難。失敗的原因有很多種:innodb鎖超時、死鎖、mysqlserver和mysqlclient的max_allowed_packet設置不一樣等等

 

那我們如何克服這些限制,實現一個可靠的基於時間點的恢復呢?

我們可以在需要恢復的server上還原一個備份;用所需的最少的數據再構建第二個server,並將所有的binlogs拷貝到這個“假的”server的datadir中。將第一個server作為第二個server的slave,然后進行純碎的主從復制。

 

為了描述這個過程,我用了一個docker容器。本地實例運行在3306的端口上,並將數據還原到本地運行的mysql下。(本地實例相當於上面說的第一個實例,docker容器實例相當於上面說的第二個實例)

基於時間恢復的日志位置是:

[root@localhost ~]# cat /var/lib/mysql/xtrabackup_binlog_info
master-bin.000007 1518932

創建目錄用於存放docker容器中的mysql的數據:

mkdir /tmp/pitr
chown -R 1001 /tmp/pitr

啟動容器,從上面的xtrabackup_binlog_info可以看到binlog的名字是master-bin

docker run --name ps_pitr -v /tmp/pitr:/var/lib/mysql 
-p 3307:3306 -e MYSQL_ROOT_PASSWORD=secret
-d percona/percona-server:5.7.18
--log_bin=master-bin --server-id=10

這里將server-id設置成之前一樣,為了以防需要使用GTID,這里將設置了--gtid_mode=on,--enforce_gtid_consistency=on。

上面的命令啟動了一個mysql 實例,調用了mysqld -initialize,設置了root的密碼和端口。端口映射到本地的3307。現在,我要關閉docker容器中的實例,移除已經生成的binlog,並將用來做基於時間點恢復的日志全部拷貝到docker容器對應的數據目錄下:

docker stop ps_pitr
rm /tmp/pitr/master-bin.*
tar -zxf binlogs.tgz -C /tmp/pitr
chown -R 1001 /tmp/pitr/master-bin.*
docker start ps_pitr

如果一切都正確,此時我們可以看到,docker容器中的mysql實例下,有了所有的binary日志清單:

mysql -u root -psecret -P 3307 --protocol=TCP -e "SHOW BINARY LOGS"
mysql: [Warning] Using a password on the command line interface can be insecure.
+-------------------+-----------+
| Log_name         | File_size |
+-------------------+-----------+
| master-bin.000005 | 26216208 |
| master-bin.000006 | 26214614 |
| master-bin.000007 | 26214902 |
. . .
| master-bin.000074 |       154 |
+-------------------+-----------+

現在,我們連接到本地實例(數據庫已經做了restore),並將其配置成3307的從庫:

mysql -u root -p
Enter password:
Welcome to the MySQL monitor. Commands end with ; or g.
Your MySQL connection id is 6
Server version: 5.7.18-16 Percona Server (GPL), Release 16, Revision d7301f8

Copyright (c) 2009-2017 Percona LLC and/or its affiliates
Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or 'h' for help. Type 'c' to clear the current input statement.

mysql> CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_PORT=3307, MASTER_USER='root', MASTER_PASSWORD='secret', MASTER_LOG_FILE='master-bin.000007', MASTER_LOG_POS=1518932;
Query OK, 0 rows affected, 2 warnings (0.01 sec)

mysql> START SLAVE;
Query OK, 0 rows affected (0.01 sec)

mysql> SHOW SLAVE STATUSG
*************************** 1. row ***************************
              Slave_IO_State: Waiting for master to send event
                Master_Host: 127.0.0.1
                Master_User: root
                Master_Port: 3307
              Connect_Retry: 60
            Master_Log_File: master-bin.000008
        Read_Master_Log_Pos: 449696
              Relay_Log_File: localhost-relay-bin.000002
              Relay_Log_Pos: 28957
      Relay_Master_Log_File: master-bin.000007
            Slave_IO_Running: Yes
          Slave_SQL_Running: Yes
            Replicate_Do_DB:
        Replicate_Ignore_DB:
          Replicate_Do_Table:
      Replicate_Ignore_Table:
    Replicate_Wild_Do_Table:
Replicate_Wild_Ignore_Table:
                  Last_Errno: 0
                  Last_Error:
                Skip_Counter: 0
        Exec_Master_Log_Pos: 15217950
            Relay_Log_Space: 11476311
            Until_Condition: None
              Until_Log_File:
              Until_Log_Pos: 0
          Master_SSL_Allowed: No
          Master_SSL_CA_File:
          Master_SSL_CA_Path:
            Master_SSL_Cert:
          Master_SSL_Cipher:
              Master_SSL_Key:
      Seconds_Behind_Master: 4382
Master_SSL_Verify_Server_Cert: No
              Last_IO_Errno: 0
              Last_IO_Error:
              Last_SQL_Errno: 0
              Last_SQL_Error:
Replicate_Ignore_Server_Ids:
            Master_Server_Id: 10
                Master_UUID: 80b9fe26-a945-11e7-aa1d-0242ac110002
            Master_Info_File: /var/lib/mysql/master.info
                  SQL_Delay: 0
        SQL_Remaining_Delay: NULL
    Slave_SQL_Running_State: Opening tables
          Master_Retry_Count: 86400
                Master_Bind:
    Last_IO_Error_Timestamp:
    Last_SQL_Error_Timestamp:
              Master_SSL_Crl:
          Master_SSL_Crlpath:
          Retrieved_Gtid_Set:
          Executed_Gtid_Set:
              Auto_Position: 0
        Replicate_Rewrite_DB:
                Channel_Name:
          Master_TLS_Version:
1 row in set (0.17 sec)

. . .

mysql> SHOW SLAVE STATUSG
*************************** 1. row ***************************
              Slave_IO_State: Waiting for master to send event
                Master_Host: 127.0.0.1
                Master_User: root
                Master_Port: 3307
              Connect_Retry: 60
            Master_Log_File: master-bin.000074
        Read_Master_Log_Pos: 154
              Relay_Log_File: localhost-relay-bin.000133
              Relay_Log_Pos: 381
      Relay_Master_Log_File: master-bin.000074
            Slave_IO_Running: Yes
          Slave_SQL_Running: Yes
            Replicate_Do_DB:
        Replicate_Ignore_DB:
          Replicate_Do_Table:
      Replicate_Ignore_Table:
    Replicate_Wild_Do_Table:
Replicate_Wild_Ignore_Table:
                  Last_Errno: 0
                  Last_Error:
                Skip_Counter: 0
        Exec_Master_Log_Pos: 154
            Relay_Log_Space: 819
            Until_Condition: None
              Until_Log_File:
              Until_Log_Pos: 0
          Master_SSL_Allowed: No
          Master_SSL_CA_File:
          Master_SSL_CA_Path:
            Master_SSL_Cert:
          Master_SSL_Cipher:
              Master_SSL_Key:
      Seconds_Behind_Master: 0
Master_SSL_Verify_Server_Cert: No
              Last_IO_Errno: 0
              Last_IO_Error:
              Last_SQL_Errno: 0
              Last_SQL_Error:
Replicate_Ignore_Server_Ids:
            Master_Server_Id: 10
                Master_UUID: 80b9fe26-a945-11e7-aa1d-0242ac110002
            Master_Info_File: /var/lib/mysql/master.info
                  SQL_Delay: 0
        SQL_Remaining_Delay: NULL
    Slave_SQL_Running_State: Slave has read all relay log; waiting for more updates
          Master_Retry_Count: 86400
                Master_Bind:
    Last_IO_Error_Timestamp:
    Last_SQL_Error_Timestamp:
              Master_SSL_Crl:
          Master_SSL_Crlpath:
          Retrieved_Gtid_Set:
          Executed_Gtid_Set:
              Auto_Position: 0
        Replicate_Rewrite_DB:
                Channel_Name:
          Master_TLS_Version:
1 row in set (0.01 sec)

如果只是想將日志應用到某個具體的時間點,可以用mysqlbinlog來確認位置(或gtid),使用START SLAVE UNTIL MASTER_LOG_FILE = 'log_name', MASTER_LOG_POS = log_pos或START SLAVE SQL_THREAD UNTIL SQL_AFTER_GTIDS = '3E11FA47-71CA-11E1-9E33-C80AA9429562:11-56'

 

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM