在当今数字化的时代,数据已经成为了企业和个人最宝贵的资产之一。数据不仅仅是简单的信息集合,它更是决策的依据、业务的支撑以及创新的源泉。
数据丢失是一种极其危险且令人头疼的情况。想象一下,企业因系统故障、人为误操作或遭受恶意攻击而丢失了关键的业务数据,这可能导致业务中断、客户流失,甚至面临法律风险和声誉损害。
在这样的背景下,有效的数据管理和保护工具就显得尤为重要。在之前的社区文章中,有介绍过一款闪回工具binlog2sql
但今天介绍的闪回工具相对已有的回滚工具,其增加了更多的过滤选项,性能优于 binlog2sql
、MySQLbinlog
除使用工具还可以手动恢复数据,详见推文:
MyFlash 是由美团点评公司技术工程部开发维护的一个回滚DML操作的工具。该工具通过解析 v4 版本的 binlog,完成回滚操作。相对已有的回滚工具,其增加了更多的过滤选项,让回滚更加容易。
该工具开源地址为:https://github.com/Meituan-Dianping/MyFlash
binlog格式必须为row,且binlog_row_image=full
仅支持 MySQL5.6 与 MySQL5.7
只能回滚DML(增、删、改)
介绍说只支持 5.6 与 5.7 版本,但在 GreatSQL 8.0.32-26 版本测试中也可用
拉取工具仓库,并编译安装
$ Git clone https://github.com/Meituan-Dianping/MyFlash.git
$ gcc -w `pkg-config --cflags --libs glib-2.0` source/binlogParseGlib.c -o binary/flashback
若不想每次去重新编译,可以选择使用静态链接,但是该方法需要知道glib库的版本和位置,因此对于每台机器略有不同,请谨慎使用
$ gcc -w -g `pkg-config --cflags glib-2.0` source/binlogParseGlib.c -o binary/flashback /usr/lib64/libglib-2.0.a -lrt
编译完成后,在binary
目录下有可执行文件flashbaC++k
$ ./binary/flashback -help
Usage:
flashback [OPTION?]
Help Options:
-h, --help Show help options
Application Options:
--databaseNames databaseName to apply. if multiple, seperate by comma(,)
--tableNames tableName to apply. if multiple, seperate by comma(,)
--tableNames-file tableName to apply. if multiple, seperate by comma(,)
--start-position start position
--stop-position stop position
--start-datetime start time (format %Y-%m-%d %H:%M:%S)
--stop-datetime stop time (format %Y-%m-%d %H:%M:%S)
--sqlTypes sql type to filter . support INSERT, UPDATE ,DELETE. if multiple, seperate by comma(,)
--maxSplitSize max file size after split, the uint is M
--binlogFileNames binlog files to process. if multiple, seperate by comma(,)
--outBinlogFileNameBase output binlog file name base
--logLevel log level, available option is debug,warning,error
--include-gtids gtids to process. if multiple, seperate by comma(,)
--include-gtids-file gtids to process. if multiple, seperate by comma(,)
--exclude-gtids gtids to skip. if multiple, seperate by comma(,)
--exclude-gtids-file gtids to skip. if multiple, seperate by comma(,)
此次测试环境情况如下:
创建一个test
库和students
表,并插入 5 条数据
greatsql> CREATE TABLE students (
id INT AUTO_INCREMENT PRIMARY KEY,
first_name VARCHAR(50),
last_name VARCHAR(50),
age INT,
grade VARCHAR(10),
city VARCHAR(50)
);
greatsql> INSERT INTO students (first_name, last_name, age, grade, city) VALUES
('Alice', 'Smith', 18, 'Grade 12', 'New York'),
('Bob', 'Johnson', 17, 'Grade 11', 'Los Angeles'),
('Charlie', 'Williams', 16, 'Grade 10', 'ChicaGo'),
('David', 'Brown', 15, 'Grade 9', 'Houston'),
('Eve', 'Davis', 17, 'Grade 11', 'Miami');
模拟误操作将 age 列全部修改为0
greatsql> UPDATE students SET age = 0;
greatsql> SELECT * FROM students;
+----+------------+-----------+------+----------+-------------+
| id | first_name | last_name | age | grade | city |
+----+------------+-----------+------+----------+-------------+
| 1 | Alice | Smith | 0 | Grade 12 | New York |
| 2 | Bob | Johnson | 0 | Grade 11 | Los Angeles |
| 3 | Charlie | Williams | 0 | Grade 10 | Chicago |
| 4 | David | Brown | 0 | Grade 9 | Houston |
| 5 | Eve | Davis | 0 | Grade 11 | Miami |
+----+------------+-----------+------+----------+-------------+
5 rows in set (0.00 sec)
记录误操作时间,并使用FLUSH LOGS
换一个 Binary Log 记录,查看 Binary Log 文件名
greatsql> SELECT current_timestamp();
+---------------------+
| current_timestamp() |
+---------------------+
| 2024-08-08 14:41:05 |
+---------------------+
greatsql> FLUSH LOGS;
Query OK, 0 rows affected (0.06 sec)
greatsql> SHOW BINARY LOGS;
+---------------+-----------+-----------+
| Log_name | File_size | Encrypted |
+---------------+-----------+-----------+
| binlog.000006 | 2146 | No |
| binlog.000007 | 197 | No |
+---------------+-----------+-----------+
要用闪回需要注意闪回的时间点,例如这次的需求是,闪回到 INSERT INTO
5条语句后
$ mysqlbinlog --no-defaults -v binlog.000006
# 发生误操作的时间`14:33:56`及开始位置`1359`和结束位置`2102`
MyFlash 解析闪回文件
$ ./flashback --databaseNames=test --tableNames=students --start-position='1359' --stop-position='2102' --binlogFileNames=/data/greatsql/binlog.000006 --outBinlogFileNameBase=students
如果确定误操作类型也可以加上
--sqlTypes=UPDATE/INSERT/DELETE
(多类型用','隔开)
生成文件 students.flashback
并查看
$ mysqlbinlog --no-defaults --base64-output=decode-rows -v students.flashback
# 可以看到文件中将 UPDATE 语句进行回滚
# ... 节选 ...
### UPDATE `test`.`students`
### WHERE
### @1=1
### @2='Alice'
### @3='Smith'
### @4=0
### @5='Grade 12'
### @6='New York'
### SET
### @1=1
### @2='Alice'
### @3='Smith'
### @4=18
### @5='Grade 12'
### @6='New York'
执行闪回恢复
$ gcc -w `pkg-config --cflags --libs glib-2.0` source/binlogParseGlib.c -o binary/flashback
0
再次查看数据,已经恢复
$ gcc -w `pkg-config --cflags --libs glib-2.0` source/binlogParseGlib.c -o binary/flashback
1
回滚该文件中指定语句
回滚该文件中所有 INSTER
语句,UPDATE/DELETE
语句也同理
$ gcc -w `pkg-config --cflags --libs glib-2.0` source/binlogParseGlib.c -o binary/flashback
2
回滚大文件
该工具中有maxSplitSize
参数,可用于切割大文件
$ gcc -w `pkg-config --cflags --libs glib-2.0` source/binlogParseGlib.c -o binary/flashback
3
和社区上次推荐的 binlog2sql 测试下性能,看哪个恢复速度快
创建 orders 表
$ gcc -w `pkg-config --cflags --libs glib-2.0` source/binlogParseGlib.c -o binary/flashback
4
创建 Shell 脚本,并插入 110504 条数据
$ gcc -w `pkg-config --cflags --libs glib-2.0` source/binlogParseGlib.c -o binary/flashback
5
退出后执行脚本,并查看数据量
$ gcc -w `pkg-config --cflags --libs glib-2.0` source/binlogParseGlib.c -o binary/flashback
6
模拟误操作删除数据
$ gcc -w `pkg-config --cflags --libs glib-2.0` source/binlogParseGlib.c -o binary/flashback
7
查看 Binary Log 日志,找到误操作位置
$ gcc -w `pkg-config --cflags --libs glib-2.0` source/binlogParseGlib.c -o binary/flashback
8
使用 MyFlash 生成恢复的 Binary Log
$ gcc -w `pkg-config --cflags --libs glib-2.0` source/binlogParseGlib.c -o binary/flashback
9
查看生成的文件,并使用 mysqlbinlog 回滚恢复
$ gcc -w -g `pkg-config --cflags glib-2.0` source/binlogParseGlib.c -o binary/flashback /usr/lib64/libglib-2.0.a -lrt
0
查看数据恢复情况
$ gcc -w -g `pkg-config --cflags glib-2.0` source/binlogParseGlib.c -o binary/flashback /usr/lib64/libglib-2.0.a -lrt
1
用切割的方式导入
$ gcc -w -g `pkg-config --cflags glib-2.0` source/binlogParseGlib.c -o binary/flashback /usr/lib64/libglib-2.0.a -lrt
2
切割后的文件名无法修改,只能叫 binlog_output_base
如果切割的文件多了,需要写个小脚本导入这些切割后的文件
$ gcc -w -g `pkg-config --cflags glib-2.0` source/binlogParseGlib.c -o binary/flashback /usr/lib64/libglib-2.0.a -lrt
3
运行 batch_rollback.sh
导入
$ gcc -w -g `pkg-config --cflags glib-2.0` source/binlogParseGlib.c -o binary/flashback /usr/lib64/libglib-2.0.a -lrt
4
根据 MyFlash 官方的测试结果和 mysqlbinlog、binlog2sql 两款工具对比,恢复100万条数据
Enjoy GreatSQL
GreatSQL是适用于金融级应用的国内自主开源数据库,具备高性能、高可靠、高易用性、高安全等多个核心特性,可以作为MySQL或Percona Server的可选替换,用于线上生产环境,且完全免费并兼容MySQL或Percona Server。
相关链接: GreatSQL社区 Gitee GitHub Bilibili
社区博客有奖征稿详情:https://greatsql.cn/thread-100-1-1.html
微信:扫码添加
GreatSQL社区助手
微信好友,发送验证信息加群
。