详解MySQL数据恢复( 三 )


chengqm-3307>>show slave status G;... Master_Port: 3306 Connect_Retry: 60 Master_Log_File: mysql-bin.000039 Read_Master_Log_Pos: 15524 Relay_Log_File: mysql-relay-bin.000002 Relay_Log_Pos: 22845 Relay_Master_Log_File: mysql-bin.000038 Slave_IO_Running: Yes Slave_SQL_Running: Yes... Seconds_Behind_Master: 600...当前节点二表
chengqm-3307>>show tables;+------------------+| Tables_in_mytest |+------------------+| a || b |+------------------+在节点一删除表 b
chengqm-3306>>drop table b;Query OK, 0 rows affected (0.00 sec)chengqm-3306>>show tables;+------------------+| Tables_in_mytest |+------------------+| a |+------------------+1 row in set (0.00 sec)接下来就是跳过这条 SQL 的操作步骤
1 延迟库停止同步
stop slave;2 找出执行了 drop table 语句的前一句的 pos 位置
[mysql@mysql-test ~]$ mysqlbinlog -vv /data/mysql_log/mysql_test/mysql-bin.000039 | grep -i -B 10 'drop table `b`';...# at 35134#190819 11:40:25 server id 83 end_log_pos 35199 CRC32 0x02771167 Anonymous_GTID last_committed=132 sequence_number=133 rbr_only=noSET @@SESSION.GTID_NEXT= 'ANONYMOUS'/*!*/;# at 35199#190819 11:40:25 server id 83 end_log_pos 35317 CRC32 0x50a018aa Query thread_id=37155 exec_time=0 error_code=0use `mytest`/*!*/;SET TIMESTAMP=1566186025/*!*/;DROP TABLE `b` /* generated by server */从结果中我们可以看到 drop 所在语句的前一句开始位置是 35134,所以我们同步到 35134 (这个可别选错了)
3 延迟库同步到要跳过的 SQL 前一条
change master to master_delay=0;start slave until master_log_file='mysql-bin.000039',master_log_pos=35134;查看状态看到已经同步到对应节点
chengqm-3307>>show slave status G;... Master_Port: 3306 Connect_Retry: 60 Master_Log_File: mysql-bin.000039 Read_Master_Log_Pos: 65792... Slave_IO_Running: Yes Slave_SQL_Running: No Exec_Master_Log_Pos: 35134... Until_Log_File: mysql-bin.000039 Until_Log_Pos: 351344 跳过一条 SQL 后开始同步
set global sql_slave_skip_counter=1;start slave;查看同步状态,删除表 b 的语句已经被跳过
chengqm-3307>>show slave status G;... Slave_IO_Running: Yes Slave_SQL_Running: Yes...1 row in set (0.00 sec)chengqm-3307>>show tables;+------------------+| Tables_in_mytest |+------------------+| a || b |+------------------+2 rows in set (0.00 sec)4.2.2 开启 GTID
使用 GTID 跳过的步骤会简单很多,只要执行一条和要跳过的 SQL 的 GTID 相同的事务就可以跳过了
1.停止同步
2.找出执行了 drop table 语句的 GTID
3.执行这个 GTID 的事务
SET SESSION GTID_NEXT='对应的 GTID 值';BEGIN; COMMIT;SET SESSION GTID_NEXT = AUTOMATIC;4.继续同步
5.闪回
闪回操作就是反向操作,比如执行了 delete from a where id=1,闪回就会执行对应的插入操作 insert into a (id,…) values(1,…),用于误操作数据,只对 DML 语句有效,且要求 binlog 格式设为 ROW 。本章介绍两个比较好用的开源工具
5.1.binlog2sql
binlog2sql 是大众点评开源的一款用于解析 binlog 的工具,可以用于生成闪回语句,项目地址 binlog2sql
5.1.1.安装
wget https://github.com/danfengcao/binlog2sql/archive/master.zip -O binlog2sql.zipunzip binlog2sql.zipcd binlog2sql-master/# 安装依赖pip install -r requirements.txt5.1.2 生成回滚SQL
Python binlog2sql/binlog2sql.py --flashback -h<host> -P<port> -u<user> -p'<password>' -d<dbname> -t<table_name>--start-file='<binlog_file>' --start-datetime='<start_time>' --stop-datetime='<stop_time>' > ./flashback.sqlpython binlog2sql/binlog2sql.py --flashback -h<host> -P<port> -u<user> -p'<password>' -d<dbname> -t<table_name> --start-file='<binlog_file>' --start-position=<start_pos> --stop-position=<stop_pos> > ./flashback.sql5.2 MyFlash
MyFlash 是由美团点评公司技术工程部开发维护的一个回滚 DML 操作的工具,项目链接 MyFlash
限制:

  • binlog格式必须为row,且 binlog_row_image=full
  • 仅支持5.6与5.7
  • 只能回滚DML(增、删、改)
5.2.1 安装
# 依赖(centos)yum install gcc* pkg-config glib2 libgnomeui-devel -y# 下载文件wget https://github.com/Meituan-Dianping/MyFlash/archive/master.zip -O MyFlash.zipunzip MyFlash.zipcd MyFlash-master# 编译安装gcc -w `pkg-config --cflags --libs glib-2.0` source/binlogParseGlib.c -o binary/flashbackmv binary /usr/local/MyFlashln -s /usr/local/MyFlash/flashback /usr/bin/flashback5.2.2 使用
生成回滚语句
flashback --databaseNames=<dbname> --binlogFileNames=<binlog_file> --start-position=<start_pos> --stop-position=<stop_pos>执行后会生成 binlog_output_base.flashback 文件,需要用 mysqlbinlog 解析出来再使用


推荐阅读