Mysql-数据闪回工具MyFlash

前言

MyFlash 是由美团点评公司技术工程部开发维护的一个回滚DML操作的工具。

  • 可以针对实例、数据库、表及指定的DML语句进行回滚
  • 如果binlog日志保留,可以闪回到任意时间

限制:

  1. binlog格式必须为row,且binlog_row_image=full

  2. 仅支持 MySQL5.6 与 MySQL5.7

  3. 只能回滚DML(增、删、改)

一、下载安装

$ cd /export/tmp

$ wget https://github.com/Meituan-Dianping/MyFlash/archive/master.zip

$ unzip master.zip

$ cd MyFlash-master

$ yum -y install gcc glib2-devel 

#配置软链接
$ ln -s /export/tmp/MyFlash-master/binary/flashback /usr/bin/flashback

二、用法

常用参数说明:
--databaseNames
指定需要回滚的数据库名。多个数据库可以用 “,” 隔开。如果不指定该参数,相当于指定了所有数据库。

--tableNames
指定需要回滚的表名。多个表可以用 “,” 隔开。如果不指定该参数,相当于指定了所有表。

--start-position
指定回滚开始的位置。如不指定,从文件的开始处回滚。请指定正确的有效的位置,否则无法回滚。

--stop-position
指定回滚结束的位置。如不指定,回滚到文件结尾。请指定正确的有效的位置,否则无法回滚。

--start-datetime
指定回滚的开始时间。注意格式必须是 %Y-%m-%d %H:%M:%S。如不指定,则不限定时间。

--stop-datetime
指定回滚的结束时间。注意格式必须是 %Y-%m-%d %H:%M:%S。如不指定,则不限定时间。

--sqlTypes
指定需要回滚的 sql 类型。目前支持的过滤类型是 INSERT, UPDATE, DELETE。多个类型可以用 “,” 隔开。

--maxSplitSize
指定解析分割后文件最大大小,单位为 M。

--binlogFileNames
指定需要回滚的 binlog 文件,如有多个,用 “,” 隔开。

--outBinlogFileNameBase
指定输出的 binlog 文件前缀,如不指定,则默认为 binlog_output_base.flashback。

--logLevel
指定输出的日志级别,可选级别有 debug, warning, error,默认级别为 error 级别。

--include-gtids
指定需要回滚的 gtid,支持 gtid 的单个和范围两种形式,如有多种形式,用 “,” 隔开。

--exclude-gtids
指定不需要回滚的 gtid,支持 gtid 的单个和范围两种形式,如有多种形式,用 “,” 隔开。

三、测试验证

mysql版本:5.7.22

# 登录mysql数据库(此处省略)

# 创建库
mysql> create database myflash_test;

#进入库
mysql> use myflash_test;

#创建表并插入数据
mysql> CREATE TABLE test (
    id INT AUTO_INCREMENT PRIMARY KEY,
    name VARCHAR(50),
    age INT
);

mysql> INSERT INTO test (name, age) VALUES ('John', 20);
mysql> INSERT INTO test (name, age) VALUES ('Alice', 22);
mysql> INSERT INTO test (name, age) VALUES ('Bob', 25);
mysql> INSERT INTO test (name, age) VALUES ('Ella', 18);
mysql> INSERT INTO test (name, age) VALUES ('David', 21);

模拟误操作:

# 查询确认
mysql> select * from test;
+----+-------+------+
| id | name  | age  |
+----+-------+------+
|  1 | John  |   20 |
|  2 | Alice |   22 |
|  3 | Bob   |   25 |
|  4 | Ella  |   18 |
|  5 | David |   21 |
+----+-------+------+
5 rows in set (0.00 sec)


# 修改数据
mysql> UPDATE test SET age = 0;

# 查询确认
mysql> select * from test;
+----+-------+------+
| id | name  | age  |
+----+-------+------+
|  1 | John  |    0 |
|  2 | Alice |    0 |
|  3 | Bob   |    0 |
|  4 | Ella  |    0 |
|  5 | David |    0 |
+----+-------+------+
5 rows in set (0.00 sec)

# 确认目前使用的binlog文件
mysql> show master status;
+------------------+-----------+--------------+------------------+-----------------------------------------------+
| File             | Position  | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set                             |
+------------------+-----------+--------------+------------------+-----------------------------------------------+
| mysql-bin.000114 | 231898269 |              |                  | 704ba2fe-d2ba-11ed-901b-fa163ef1200f:1-963042 |
+------------------+-----------+--------------+------------------+-----------------------------------------------+

# 在binlog目录下过滤关于误操作的关键词
$ mysqlbinlog -vv mysql-bin.000114| less |grep -A 30 test

# 解析 binlog,确认误操作的时间段
<----------------------------以下为查询到的binlog内容,做分割----------------------------->
#250521 17:03:21 server id 393307  end_log_pos 231898060 CRC32 0xa7cbc1dc 	Table_map: `myflash_test`.`test` mapped to number 64090
# at 231898060
#250521 17:03:21 server id 393307  end_log_pos 231898238 CRC32 0xd78ecf9a 	Update_rows: table id 64090 flags: STMT_END_F

BINLOG '
2ZYtaBNbAAYAOwAAAMx70g0AAFr6AAAAAAEADG15Zmxhc2hfdGVzdAAEdGVzdAADAw8DApYABtzB
y6c=
2ZYtaB9bAAYAsgAAAH580g0AAFr6AAAAAAEAAgAD///4AQAAAARKb2huFAAAAPgBAAAABEpvaG4A
AAAA+AIAAAAFQWxpY2UWAAAA+AIAAAAFQWxpY2UAAAAA+AMAAAADQm9iGQAAAPgDAAAAA0JvYgAA
AAD4BAAAAARFbGxhEgAAAPgEAAAABEVsbGEAAAAA+AUAAAAFRGF2aWQVAAAA+AUAAAAFRGF2aWQA
AAAAms+O1w==
'/*!*/;
### UPDATE `myflash_test`.`test`
### WHERE
###   @1=1 /* INT meta=0 nullable=0 is_null=0 */
###   @2='John' /* VARSTRING(150) meta=150 nullable=1 is_null=0 */
###   @3=20 /* INT meta=0 nullable=1 is_null=0 */
### SET
###   @1=1 /* INT meta=0 nullable=0 is_null=0 */
###   @2='John' /* VARSTRING(150) meta=150 nullable=1 is_null=0 */
###   @3=0 /* INT meta=0 nullable=1 is_null=0 */
### UPDATE `myflash_test`.`test`
### WHERE
###   @1=2 /* INT meta=0 nullable=0 is_null=0 */
###   @2='Alice' /* VARSTRING(150) meta=150 nullable=1 is_null=0 */
###   @3=22 /* INT meta=0 nullable=1 is_null=0 */
### SET
###   @1=2 /* INT meta=0 nullable=0 is_null=0 */
###   @2='Alice' /* VARSTRING(150) meta=150 nullable=1 is_null=0 */
###   @3=0 /* INT meta=0 nullable=1 is_null=0 */
### UPDATE `myflash_test`.`test`
### WHERE
###   @1=3 /* INT meta=0 nullable=0 is_null=0 */
###   @2='Bob' /* VARSTRING(150) meta=150 nullable=1 is_null=0 */
###   @3=25 /* INT meta=0 nullable=1 is_null=0 */
### SET
###   @1=3 /* INT meta=0 nullable=0 is_null=0 */
###   @2='Bob' /* VARSTRING(150) meta=150 nullable=1 is_null=0 */
###   @3=0 /* INT meta=0 nullable=1 is_null=0 */
### UPDATE `myflash_test`.`test`
### WHERE
###   @1=4 /* INT meta=0 nullable=0 is_null=0 */
###   @2='Ella' /* VARSTRING(150) meta=150 nullable=1 is_null=0 */
###   @3=18 /* INT meta=0 nullable=1 is_null=0 */
### SET
###   @1=4 /* INT meta=0 nullable=0 is_null=0 */
###   @2='Ella' /* VARSTRING(150) meta=150 nullable=1 is_null=0 */
###   @3=0 /* INT meta=0 nullable=1 is_null=0 */
### UPDATE `myflash_test`.`test`
### WHERE
###   @1=5 /* INT meta=0 nullable=0 is_null=0 */
###   @2='David' /* VARSTRING(150) meta=150 nullable=1 is_null=0 */
###   @3=21 /* INT meta=0 nullable=1 is_null=0 */
### SET
###   @1=5 /* INT meta=0 nullable=0 is_null=0 */
###   @2='David' /* VARSTRING(150) meta=150 nullable=1 is_null=0 */
###   @3=0 /* INT meta=0 nullable=1 is_null=0 */
# at 231898238
#250521 17:03:21 server id 393307  end_log_pos 231898269 CRC32 0x66122cdb 	Xid = 76160547
COMMIT/*!*/;
SET @@SESSION.GTID_NEXT= 'AUTOMATIC' /* added by mysqlbinlog */ /*!*/;
DELIMITER ;
# End of log file
<----------------------------以上为查询到的binlog内容,做分割----------------------------->

# 使用 MyFlash 工具进行回滚,进入到工具的安装目录,执行命令反向解析 binlog,指定要回滚的库、表、开始时间和结束时间,并指定反向解析的 SQL 语句类型:
 flashback --databaseNames="myflash_test" --tableNames="test" --start-datetime="2025-05-21 17:03:21" --stop-datetime="2025-05-21 17:03:21"  --sqlTypes="UPDATE" --binlogFileNames=/export/servers/data/my3307/binlog/mysql-bin.000114 --outBinlogFileNameBase=test.sql

# 恢复数据
mysqlbinlog --skip-gtids test.sql.flashback | mysql -S /export/servers/data/my3307/run/mysqld.sock -usysdba -p


# 登录数据库并验证数据已正常回滚
mysql> select * from test;
+----+-------+------+
| id | name  | age  |
+----+-------+------+
|  1 | John  |   20 |
|  2 | Alice |   22 |
|  3 | Bob   |   25 |
|  4 | Ella  |   18 |
|  5 | David |   21 |
+----+-------+------+
5 rows in set (0.00 sec)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

改名叫热炸

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值