author:彭程
介绍
针对实际的运维生产需要中误操作造成表或数据被破坏,需要修复的情况,使用goflash工具可以实现mysql操作的闪回
安装说明
本机linux版本:CentOS 7.9
Mysql版本:5.7.16
Mysql开启gtid模式
从MySQL5.6开始增加了强大的GTID(Global Transaction ID,全局事务ID)特性,用来强化数据库的主备一致性, 故障恢复, 以及容错能力。GTID是由server_uuid和事务id组成的,即GTID=server_uuid:transaction_id。goflash也是基于这个特性实现的数据闪回,因此使用goflash的前提Mysql数据库开启gtid。
修改Mysql配置文件my.cnf,增加以下配置
log-bin=mysql-binlog-slave-updates=ONsync_binlog=1binlog_format=rowgtid_mode=ONenforce_gtid_consistency=true
log-bin:开启bin-log日志;
log-slave-update:主从同步配置项,应用链式复制服务器,保证多主多从数据一致;
sync_binlog:表示事务提交频率,默认是0,最安全的是设置为1;
binlog_format:日志模式,有三种:- row:日志中会记录成每一行数据被修改的形式,然后在 slave 端再对相同的数据进行修改;
- tatement:每一条会修改数据的 SQL 都会记录到 master 的 bin-log 中。slave 在复制的时候 SQL 进程会解析成和原来 master 端执行过的相同的 SQL 再次执行;
- Mixed:在 Mixed 模式下,MySQL 会根据执行的每一条具体的 SQL 语句来区分对待记录的日志形式,也就是在 statement 和 row 之间选择一种。
gtid_mode:gtid模式开启标志;
enforce_gtid_consistency:启动强制GTID的一致性,如果开启GTID功能则此参数必须要开启
重启Mysql后,show master status就可以看到gtid
mysql> show master status;+------------------+----------+--------------+------------------+------------------------------------------+| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |+------------------+----------+--------------+------------------+------------------------------------------+| mysql-bin.000001 | 1563 | | | 5ab5bc2a-e8f8-11eb-ade0-000c2949185c:1-6 |+------------------+----------+--------------+------------------+------------------------------------------+
goflash工具按数据库进行闪回
原始表如下: ``` mysql> select * from pet; +———+———+ | id | name | +———+———+ | 1 | dog | | 2 | cat | | 3 | cat | +———+———+ 3 rows in set (0.00 sec)
mysql> reset master; Query OK, 0 rows affected (0.14 sec)
mysql> show master status; +—————————+—————+———————+—————————+—————————-+ | File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set | +—————————+—————+———————+—————————+—————————-+ | mysql-bin.000001 | 154 | | | | +—————————+—————+———————+—————————+—————————-+ 1 row in set (0.00 sec)
- 插入两行新数据:
mysql> insert into pet values(4,’fish’);
Query OK, 1 row affected (0.00 sec)
mysql> insert into pet values(5,’pig’);
Query OK, 1 row affected (0.10 sec)
- bin-log状态如下:
mysql> show master status; +—————————+—————+———————+—————————+—————————————————————+ | File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set | +—————————+—————+———————+—————————+—————————————————————+ | mysql-bin.000001 | 687 | | | 5ab5bc2a-e8f8-11eb-ade0-000c2949185c:1-2 | +—————————+—————+———————+—————————+—————————————————————+ 1 row in set (0.00 sec)
mysql> show binlog events in ‘mysql-bin.000001’; +—————————+——-+————————+—————-+——————-+—————————————————————————————————-+ | Log_name | Pos | Event_type | Server_id | End_log_pos | Info | +—————————+——-+————————+—————-+——————-+—————————————————————————————————-+ | mysql-bin.000001 | 4 | Format_desc | 3306 | 123 | Server ver: 5.7.16-debug-log, Binlog ver: 4 | | mysql-bin.000001 | 123 | Previous_gtids | 3306 | 154 | | | mysql-bin.000001 | 154 | Gtid | 3306 | 219 | SET @@SESSION.GTID_NEXT= ‘5ab5bc2a-e8f8-11eb-ade0-000c2949185c:1’ | | mysql-bin.000001 | 219 | Query | 3306 | 296 | BEGIN | | mysql-bin.000001 | 296 | Table_map | 3306 | 345 | table_id: 108 (test.pet) | | mysql-bin.000001 | 345 | Write_rows | 3306 | 390 | table_id: 108 flags: STMT_END_F | | mysql-bin.000001 | 390 | Xid | 3306 | 421 | COMMIT / xid=103 / | | mysql-bin.000001 | 421 | Gtid | 3306 | 486 | SET @@SESSION.GTID_NEXT= ‘5ab5bc2a-e8f8-11eb-ade0-000c2949185c:2’ | | mysql-bin.000001 | 486 | Query | 3306 | 563 | BEGIN | | mysql-bin.000001 | 563 | Table_map | 3306 | 612 | table_id: 108 (test.pet) | | mysql-bin.000001 | 612 | Write_rows | 3306 | 656 | table_id: 108 flags: STMT_END_F | | mysql-bin.000001 | 656 | Xid | 3306 | 687 | COMMIT / xid=104 / | +—————————+——-+————————+—————-+——————-+—————————————————————————————————-+ 12 rows in set (0.00 sec)
- 利用goflash工具按库进行闪回:
root@localhost data]# ./goflash -databases test -file mysql-bin.000001
#
binlog file is [mysql-bin.000001]
startpos is 0
starttime is
stoptime is
gtid is
#
Start time :2021-08-05 23:14:52.923013238 -0700 PDT m=+0.001338106 Parse file mysql-bin.000001 Finish file mysql-bin.000001
Stop time :2021-08-05 23:14:52.923720768 -0700 PDT m=+0.002045634
- 可以看到已经生成了mysql-bin.000001.flash和mysql-bin.000001.info两个文件,其中info文件如下:
ate: [2021-08-05 23:14:23] GTID_NEXT: 5ab5bc2a-e8f8-11eb-ade0-000c2949185c:1 1 rows affected !
Date: [2021-08-05 23:14:23] GTID_NEXT: 5ab5bc2a-e8f8-11eb-ade0-000c2949185c:2 1 rows affected !
GTID SET is 5ab5bc2a-e8f8-11eb-ade0-000c2949185c:1-2 Sum 2 rows affected !
- 进行闪回并查看数据库,插入的数据已经没有了
mysqlbinlog —skip-gtids mysql-bin.000001.flash | mysql —socket=/tmp/mysql.sock -uroot -p mysql> select * from pet; +———+———+ | id | name | +———+———+ | 1 | dog | | 2 | cat | | 3 | cat | +———+———+ 3 rows in set (0.00 sec)
<a name="dJBqd"></a>## goflash工具按gtid进行闪回- 原始表插入两行数据:
mysql> reset master; Query OK, 0 rows affected (0.01 sec)
mysql> insert into pet values(4,’pig’);
Query OK, 1 row affected (0.00 sec)
mysql> insert into pet values(5,’bird’);
Query OK, 1 row affected (0.01 sec)
mysql> select * from pet; +———+———+ | id | name | +———+———+ | 1 | dog | | 2 | cat | | 3 | cat | | 4 | pig | | 5 | bird | +———+———+ 5 rows in set (0.00 sec)
mysql> show binlog events in ‘mysql-bin.000001’; +—————————+——-+————————+—————-+——————-+—————————————————————————————————-+ | Log_name | Pos | Event_type | Server_id | End_log_pos | Info | +—————————+——-+————————+—————-+——————-+—————————————————————————————————-+ | mysql-bin.000001 | 4 | Format_desc | 3306 | 123 | Server ver: 5.7.16-debug-log, Binlog ver: 4 | | mysql-bin.000001 | 123 | Previous_gtids | 3306 | 154 | | | mysql-bin.000001 | 154 | Gtid | 3306 | 219 | SET @@SESSION.GTID_NEXT= ‘5ab5bc2a-e8f8-11eb-ade0-000c2949185c:1’ | | mysql-bin.000001 | 219 | Query | 3306 | 296 | BEGIN | | mysql-bin.000001 | 296 | Table_map | 3306 | 345 | table_id: 108 (test.pet) | | mysql-bin.000001 | 345 | Write_rows | 3306 | 389 | table_id: 108 flags: STMT_END_F | | mysql-bin.000001 | 389 | Xid | 3306 | 420 | COMMIT / xid=122 / | | mysql-bin.000001 | 420 | Gtid | 3306 | 485 | SET @@SESSION.GTID_NEXT= ‘5ab5bc2a-e8f8-11eb-ade0-000c2949185c:2’ | | mysql-bin.000001 | 485 | Query | 3306 | 562 | BEGIN | | mysql-bin.000001 | 562 | Table_map | 3306 | 611 | table_id: 108 (test.pet) | | mysql-bin.000001 | 611 | Write_rows | 3306 | 656 | table_id: 108 flags: STMT_END_F | | mysql-bin.000001 | 656 | Xid | 3306 | 687 | COMMIT / xid=123 / | +—————————+——-+————————+—————-+——————-+—————————————————————————————————-+ 12 rows in set (0.00 sec)
- 现在想闪回id=4的插入操作,查看binlog可知gtid为5ab5bc2a-e8f8-11eb-ade0-000c2949185c:1,按此gtid进行过滤闪回:
[root@localhost data]# ./goflash -gtid 5ab5bc2a-e8f8-11eb-ade0-000c2949185c:1 -file mysql-bin.000001
#
binlog file is [mysql-bin.000001]
startpos is 0
starttime is
stoptime is
gtid is 5ab5bc2a-e8f8-11eb-ade0-000c2949185c:1
#
Start time :2021-08-05 23:34:40.794301299 -0700 PDT m=+0.000759375 Parse file mysql-bin.000001 Finish file mysql-bin.000001
Stop time :2021-08-05 23:34:40.794747382 -0700 PDT m=+0.001205442 [root@localhost data]# mysqlbinlog —skip-gtids mysql-bin.000001.flash | mysql —socket=/tmp/mysql.sock -uroot -p
- 查看结果,闪回成功
mysql> select * from pet; +———+———+ | id | name | +———+———+ | 1 | dog | | 2 | cat | | 3 | cat | | 5 | bird | +———+———+ 4 rows in set (0.00 sec) ```
