DROP DB或DROP TABLE場景下藉助SQL Thread快速應用binlog恢復方案
【問題】
假設有這種場景,誤操作DROP DB或TABLE,常規的恢復操作是還原全備份,並用mysqlbinlog追加到drop操作前的位置。
如果需要恢復的binlog的日誌量比較大而我們只希望恢復某個DB或某張表,常規操作會花費較長的時間。
在網上看到了藉助SQL Thread來應用binlog的方法,做測試驗證是可行的。
【原理】
1、Binlog是MySQL Server產⽣的,記錄資料庫的邏輯變化
2、Relay-log 是Master/Slave結構中Slave的IO_thread從主庫獲取變更日誌,記錄到slave本地
3、binlog和Relay-log實際記錄的內容是完全一致的
【實現思路】
1、將源伺服器需要追加的binlog檔案拷貝到目標伺服器資料目錄下,修改為relay-log的命名規範
2、CHANGE REPLICATION FILTER REPLICATE_DO_TABLE=(db1.t1);設定過濾只複製某個DB或某張表
3、然後使用START SLAVE SQL_THREAD UNTIL SQL_BEFORE_GTIDS語法還原到指定的GTID位置
4、開啟並行複製加速binlog應用的速度,最新的MySQL5.7.23可以使用基於WRITESET的並行複製
【測試指令碼】
(以MySQL5.7下誤DROP TABLE test.test1為例,5.6也可以用同樣的思路,但位置資訊和篩選資訊的指令碼有差異,下面指令碼供參考)
1、源例項做全備
innobackupex --socket=/data/mysql/mysql-replica01/mysql.sock --user=root --password= /data/backup
2、清空目標例項資料目錄並還原全備
innobackupex --apply-log /data/backup/2018-10-24_13-22-09
innobackupex --defaults-file=/etc/my.cnf.d/replica02.cnf --copy-back /data/backup/2018-10-24_13-22-09
3、修改資料目錄檔案許可權
chown -R mysql:mysql *
4、啟動目標例項
5、連線目標例項,隨便指定一個master_host資訊,這個命令只是為了標識目標例項是slave角色
CHANGE MASTER TO MASTER_HOST='192.192.192.192';
7、清理資料目錄下生成的relay-log相關檔案
rm -rf *relay*
8、將源例項的binlog備份拷貝到目錄例項資料目錄下,並修改命名規則,並修改許可權
cp /data/mysql/mysql-replica01/TEST-bin.000414 /data/mysql/mysql-replica02
cp /data/mysql/mysql-replica01/TEST-bin.000415 /data/mysql/mysql-replica02
mv TEST-bin.000414 TEST-relay-bin.000414
mv TEST-bin.000415 TEST-relay-bin.000415
echo './TEST-relay-bin.000414' > TEST-relay-bin.index
echo './TEST-relay-bin.000415' >> TEST-relay-bin.index
chown -R mysql:mysql *
10、依據還原目錄下的xtrabackup_info檔案指定Relay_Log_File位置,但注意需要將binlog檔名稱替換為relay log的命名規則
CHANGE MASTER TO Relay_Log_File='TEST-relay-bin.000414',relay_log_pos=1126;
11、指定篩選條件,只還原某個DB或某個表
CHANGE REPLICATION FILTER REPLICATE_DO_TABLE=(test.test1);
12、還原到drop table之前的位置
START SLAVE SQL_THREAD UNTIL SQL_BEFORE_GTIDS='86c67cfe-8b18-11e8-9e4c-246e965710f8:478351666';
13、將目標表匯入到需要恢復的源例項