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,增加以下配置

    1. log-bin=mysql-bin
    2. log-slave-updates=ON
    3. sync_binlog=1
    4. binlog_format=row
    5. gtid_mode=ON
    6. enforce_gtid_consistency=true

    log-bin:开启bin-log日志;
    log-slave-update:主从同步配置项,应用链式复制服务器,保证多主多从数据一致;
    sync_binlog:表示事务提交频率,默认是0,最安全的是设置为1;
    binlog_format:日志模式,有三种:

    1. row:日志中会记录成每一行数据被修改的形式,然后在 slave 端再对相同的数据进行修改;
    2. tatement:每一条会修改数据的 SQL 都会记录到 master 的 bin-log 中。slave 在复制的时候 SQL 进程会解析成和原来 master 端执行过的相同的 SQL 再次执行;
    3. Mixed:在 Mixed 模式下,MySQL 会根据执行的每一条具体的 SQL 语句来区分对待记录的日志形式,也就是在 statement 和 row 之间选择一种。

gtid_mode:gtid模式开启标志;
enforce_gtid_consistency:启动强制GTID的一致性,如果开启GTID功能则此参数必须要开启

  • 重启Mysql后,show master status就可以看到gtid

    1. mysql> show master status;
    2. +------------------+----------+--------------+------------------+------------------------------------------+
    3. | File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
    4. +------------------+----------+--------------+------------------+------------------------------------------+
    5. | mysql-bin.000001 | 1563 | | | 5ab5bc2a-e8f8-11eb-ade0-000c2949185c:1-6 |
    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)

  1. - 插入两行新数据:

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)

  1. - 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)

  1. - 利用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

  1. - 可以看到已经生成了mysql-bin.000001.flashmysql-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 !

  1. - 进行闪回并查看数据库,插入的数据已经没有了

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)

  1. <a name="dJBqd"></a>
  2. ## goflash工具按gtid进行闪回
  3. - 原始表插入两行数据:

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)

  1. - 现在想闪回id=4的插入操作,查看binlog可知gtid5ab5bc2a-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

  1. - 查看结果,闪回成功

mysql> select * from pet; +———+———+ | id | name | +———+———+ | 1 | dog | | 2 | cat | | 3 | cat | | 5 | bird | +———+———+ 4 rows in set (0.00 sec) ```