dba+开源工具:数据恢复搭把手!MySQL二进制日志解析转换工具(附下载)

贺春旸 2023-07-19 10:24:13
工具研发者介绍

贺春旸,dbaplus社群金牌专家,凡普金科和爱钱进DBA团队负责人,《MySQL管理之道:性能调优、高可用与监控》第一&二版、《MySQL运维进阶指南》作者,曾任职于中国移动飞信、安卓机锋网。五次荣获dbaplus年度MVP,致力于MariaDB、MongoDB等开源技术的研究,主要负责数据库性能调优、监控和架构设计。

工具下载:

https://github.com/hcymysql/reverse_sql/

 

工具简介

 

reverse_sql是一个用于解析和转换MySQL二进制日志(binlog)的工具。它可以将二进制日志文件中记录的数据库更改操作(如插入、更新、删除)转换为反向的SQL语句,以便进行数据恢复。其运行模式需二进制日志设置为ROW格式。

 

该工具的主要功能和特点包括:

 

1、解析二进制日志:reverse_sql能够解析MySQL的二进制日志文件,并还原出其中的SQL语句。

 

2、生成可读的SQL:生成原始SQL和反向SQL。

 

3、支持过滤和筛选:可以根据时间范围、表、DML操作等条件来过滤出具体的误操作SQL语句。

 

4、支持多线程并发解析binlog事件。

 

请注意!reverse_sql只是将二进制日志还原为SQL语句,而不会执行这些SQL语句来修改数据库。

 

原理

 

调用官方(https://python-mysql-replication.readthedocs.io/)库来实现,通过指定的时间范围,转换为timestamp时间戳,将整个时间范围平均分配给每个线程。

 

由于BinLogStreamReader并不支持指定时间戳来进行递增解析,固在每个任务开始之前,使用上一个任务处理过的binlog_file和binlog_pos,这样后续的线程就可以获取到上一个线程处理过的binlog文件名和position,然后进行后续的并发处理。

 

假设开始时间戳start_timestamp是1625558400,线程数量num_threads是4,整个时间范围被平均分配给每个线程。那么,通过计算可以得到以下结果:

 

对于第一个线程(i=0),start_time是1625558400。

 

对于第二个线程(i=1),start_time是1625558400 + time_range。

 

对于第三个线程(i=2),start_time是1625558400 + 2 * time_range。

 

对于最后一个线程(i=3),start_time是1625558400 + 3 * time_range。

 

这样,每个线程的开始时间都会有所偏移,确保处理的时间范围没有重叠,并且覆盖了整个时间范围。最后,将结果保存在一个列表里,并对列表做升序排序,取得最终结果。

 

使用

 

  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
shell> chmod 755 reverse_sqlshell> ./reverse_sql --helpusage: reverse_sql [-h] [-ot ONLY_TABLES [ONLY_TABLES ...]] [-op ONLY_OPERATION] -H MYSQL_HOST                   -P MYSQL_PORT -u MYSQL_USER -p MYSQL_PASSWD -d MYSQL_DATABASE                   [-c MYSQL_CHARSET] --binlog-file BINLOG_FILE [--binlog-pos BINLOG_POS]                   --start-time ST --end-time ET [--max-workers MAX_WORKERS] [--print]
Binlog数据恢复,生成反向SQL语句。
options:  -h, --help            show this help message and exit  -ot ONLY_TABLES [ONLY_TABLES ...], --only-tables ONLY_TABLES [ONLY_TABLES ...]                        设置要恢复的表,多张表用,逗号分隔  -op ONLY_OPERATION, --only-operation ONLY_OPERATION                        设置误操作时的命令(insert/update/delete  -H MYSQL_HOST, --mysql-host MYSQL_HOST                        MySQL主机名  -P MYSQL_PORT, --mysql-port MYSQL_PORT                        MySQL端口号  -u MYSQL_USER, --mysql-user MYSQL_USER                        MySQL用户名  -p MYSQL_PASSWD, --mysql-passwd MYSQL_PASSWD                        MySQL密码  -d MYSQL_DATABASE, --mysql-database MYSQL_DATABASE                        MySQL数据库名  -c MYSQL_CHARSET, --mysql-charset MYSQL_CHARSET                        MySQL字符集,默认utf8  --binlog-file BINLOG_FILE                        Binlog文件  --binlog-pos BINLOG_POS                        Binlog位置,默认4  --start-time ST       起始时间  --end-time ET         结束时间  --max-workers MAX_WORKERS                        线程数,默认10  --print               将解析后的SQL输出到终端--replace             将update转换为replace操作
Example usage:shell> ./reverse_sql -ot table1 -op delete -H 192.168.198.239 -P 3336 -u admin -p hechunyang -d hcy  --binlog-file mysql-bin.000124  --start-time "2023-07-06 10:00:00"  --end-time "2023-07-06 22:00:00" 

 

当出现误操作时,只需指定误操作的时间段,其对应的binlog文件(通常你可以通过show master status得到当前的binlog文件名)以及刚才误操作的表,和具体的DML命令,比如update或者delete。

 

工具运行时,首先会进行MySQL的环境检测(if binlog_format != 'ROW' and binlog_row_image != 'FULL'),如果不同时满足这两个条件,程序直接退出。

 

工具运行后,会在当前目录下生成一个{db}_{table}_recover.sql文件,保存着原生SQL(原生SQL会加注释)和反向SQL,如果想将结果输出到前台终端,可以指定--print选项。

 

如果你想把update操作转换为replace,指定--replace选项即可,同时会在当前目录下生成一个{db}_{table}_recover_replace.sql文件。

 

图片

 

MySQL最小化用户权限:

 

  •  
  •  
  •  
  •  
> GRANT REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO `yourname`@`%`;
> GRANT SELECT ON `test`.* TO `yourname`@`%`;

 

恢复

 

在{db}_{table}_recover.sql文件中找到你刚才误操作的DML语句,然后在MySQL数据库中执行逆向工程后的SQL以恢复数据。

 

如果{db}_{table}_recover.sql文件的内容过多,也可以通过awk命令进行分割,以便更容易进行排查。

 

  •  
shell> awk '/^-- SQL执行时间/{filename = "output" ++count ".sql"; print > filename; next} {print > filename}' test_t1_recover.sql

 

不支持drop和truncate操作,因为这两个操作属于物理性删除,需要通过历史备份进行恢复。

 

注:reverse_sql支持MySQL 5.7/8.0和MariaDB,适用于CentOS 7系统。

 

2023年7月12日更新 - 分之版本:可实现进度条展示(处理binlog的event数量和耗时时间)。

 

下载方式

 

此工具现通过dbaplus社群免费为大家提供下载使用。若使用过程中有任何问题或建议,可随时与我们联系,欢迎大家试用。

 

登录以下链接即可下载:
https://github.com/hcymysql/reverse_sql/
 
>>>>

想和工具研发老师面基的看过来!

图片

 

7月21日,2023 Gdevops全球敏捷运维峰会-北京站即将盛大开幕!贺春旸老师将亲临峰会现场进行《MySQL运维进阶指南》书籍签送活动峰会倒计时两天,想要线下面基的小伙伴,码上冲呀!!!
 
贺春旸老师深耕MySQL和MariaDB技术研究十余年,长年在dbaplus社群撰文分享MySQL和MariaDB最新动态及实践,并自研多款数据库开源工具通过dbaplus社群开放下载。《MySQL运维进阶指南》是他的又一力作,该书从技术细节到管理之道,涵盖了构建和维护高性能MySQL的方方面面,系统阐述了数据库运维管理的技术体系和实战经验心得,强烈推荐给大家。了解更多请戳:dbaplus丛书丨《MySQL运维进阶指南》亮相!基于8.0的实战沉淀
 
更多开源工具&脚本下载

 

图片

 

更多开源工具及脚本获取方式:
  • 关注微信公众号【dbaplus社群】,点击菜单栏【资源下载】
  • 登陆dbaplus社群官网:http://dbaplus.cn/list-142-1.html
 
点这里了解Gdevops峰会更多详情及报名
最新评论
访客 2024年04月08日

如果字段的最大可能长度超过255字节,那么长度值可能…

访客 2024年03月04日

只能说作者太用心了,优秀

访客 2024年02月23日

感谢详解

访客 2024年02月20日

一般干个7-8年(即30岁左右),能做到年入40w-50w;有…

访客 2023年08月20日

230721

活动预告