导语

在日常工作中可能会存在误删数据的情况,今天就简单介绍下如何利用主从复制延迟从库进行数据库的快速恢复。

步骤

1.环境准备

建立一个测试的主从库,写入一些测试数据,非本文要点,过程略。

2.设置延迟同步

在原有同步信息的基础上进行如下操作,设置延迟同步1小时

#设置延迟1小时
mysql>stopslave;
mysql>CHANGEREPLICATIONSOURCETOSOURCE_DELAY=3600;
mysql>startslave;
mysql>showslavestatus\G;
***************************1.row***************************
Slave_IO_State:Waiting formastertosendevent
Master_Host:192.168.5.160
Master_User:repl
Master_Port:3314
Slave_IO_Running:Yes
Slave_SQL_Running:Yes
Seconds_Behind_Master:6536
SQL_Delay:3600->设置后,这里可以看到延迟的信息
SQL_Remaining_Delay:NULL
Retrieved_Gtid_Set:4b4539dd-2fc1-11ec-949b-70b5e873a570:2-53662
Executed_Gtid_Set:4b4539dd-2fc1-11ec-949b-70b5e873a570:1-36546,
d2c64073-2cb5-11ec-b4d1-70b5e873a570:1-2
1row in set,1warning(0.00sec)

3.假设在主库上进行了一个误删的操作

#误删一条id=9998的数据
mysql>deletefromt1 whereid=9998;
QueryOK,1rowaffected(0.32sec)

#主库已经没有了
mysql>select*fromt1 whereid=9998;
Empty set(0.00sec)

#从库还能查到数据
mysql>select*fromt1 whereid=9998;
+—–+——+——+——+——+
|id|c1|c2|c3|c4|
+—–+——+——+——+——+
|9998|983|xAP9|mQeN|8Eu2|
+—–+——+——+——+——+
1row in set(0.00sec)

4.解析主库的binlog文件

这个步骤目的是找到主库执行删除操作时候相应的GTID值的上一个GTID值

#先解析出binlog
mysqlbinlog-vvv–base64-output=decode-rowsmysql-bin.000001>01.sql

#找到被删那条记录的GTID,再往上一条记录

SET@@SESSION.GTID_NEXT= ‘4b4539dd-2fc1-11ec-949b-70b5e873a570:54230’/*!*/;
#at15959245
#21110314:43:25serverid33145160end_log_pos15959316Querythread_id=53817exec_time=0error_code=0
#at15959377
#21110314:43:25serverid33145160end_log_pos15959436Delete_rows:tableid270flags:STMT_END_F
###DELETEFROM`test`.`t1`
###WHERE
###@1=9998/*INTmeta=0nullable=0is_null=0*/
###@2=’983’/*VARSTRING(256)meta=256nullable=1is_null=0*/
###@3=’xAP9’/*VARSTRING(256)meta=256nullable=1is_null=0*/
###@4=’mQeN’/*VARSTRING(256)meta=256nullable=1is_null=0*/
###@5=’8Eu2’/*VARSTRING(256)meta=256nullable=1is_null=0*/
#at15959436
#21110314:43:25serverid33145160end_log_pos15959463Xid=163705
COMMIT/*!*/;
#at15959463

5.从库设置同步停止的时间点

通过步骤4找到的删除操作的GTID值,我们修改下从库的同步状态,需要说明的是,当主库出现误删数据的时候,延迟库一定要第一时间停止同步。

#从库同步到删数据的gtid值,再往上一条gtid,设置同步截止点,这里的gtids与主库保持一致
mysql>STOPSLAVE;
mysql>STARTREPLICAUNTILSQL_AFTER_GTIDS= ‘4b4539dd-2fc1-11ec-949b-70b5e873a570:2-54229’;
mysql>STARTSLAVE;

6.复制同步停止

#等待同步到对应截止点后,同步的SQL线程会停止
mysql>showslavestatus\G;
***************************1.row***************************
Slave_IO_State:Waiting formastertosendevent
Master_Host:192.168.5.160
Master_User:repl
Master_Port:3314
Connect_Retry:60
Slave_IO_Running:Yes
Slave_SQL_Running:No->到达设定的GTID值后,SQL线程会中断
Until_Condition:SQL_AFTER_GTIDS->设置后这里会出现同步截止的关键信息
Master_Server_Id:33145160
Master_UUID:4b4539dd-2fc1-11ec-949b-70b5e873a570
Master_Info_File:mysql.slave_master_info
SQL_Delay:3600
SQL_Remaining_Delay:NULL
Master_Retry_Count:86400
Retrieved_Gtid_Set:4b4539dd-2fc1-11ec-949b-70b5e873a570:2-54230
Executed_Gtid_Set:4b4539dd-2fc1-11ec-949b-70b5e873a570:1-54229,
d2c64073-2cb5-11ec-b4d1-70b5e873a570:1-3
Auto_Position:1

7.数据恢复

后续我们可以对这个表进行相应操作,例如把这个表导出再导入到主库,然后再恢复中间的binlog数据。

总结

以上只是模拟一条数据误删的恢复过程,通过闪回工具甚至手动找到相应误删的数据进行恢复会更快,但是对于truncate,drop,delete忘了带where条件 的删除,用闪回工具可能就没办法了,相比备份恢复用延迟库效率会更高。

另外需要注意,如果从库开启了MTS,需要注意开启 slave_preserve_commit_order=1 防止从库误删操作先执行了。

EnjoyGreatSQL:)