MySQL数据恢复工具binlog2sql

binlog2sql是一个开源的Python开发的MySQL Binlog解析工具,能够将Binlog解析为原始的SQL,也支持将Binlog解析为回滚的SQL,以便做数据恢复。

主要功能:

  • 将Binlog解析为SQL语句
  • 将Binlog解析为回滚的SQL语句

开源地址:

github.com/danfengcao/binlog2sql

支持的版本:

  • Python 2.7, 3.4+
  • MySQL 5.6, 5.7

外部依赖包:
下载源码,打开源码目录中的requirements.txt文件,即可看到依赖的外部包,如下:

  • PyMySQL==0.7.11
  • wheel==0.29.0
  • mysql-replication==0.13

通过执行如下命令,安装外部依赖包。
shell> pip install -r requirements.txt

MySQL Server的配置:

MySQL的配置,必须满足以下要求,才能正常使用binlog2sql工具。开启binlog,binlog格式必须为ROW,且binlog_row_image必须为full。

[mysqld]
server_id = 1
log_bin = /var/log/mysql/mysql-bin.log
max_binlog_size = 1G
binlog_format = row
binlog_row_image = full

binlog2sql参数选项:mysql连接选项,与mysql客户端的选项一致。

  • -h host
  • -P port
  • -u user
  • -p password

解析模式:

  • --stop-never 持续解析binlog。可选。默认False,同步至执行命令时最新的binlog位置。
  • -K, --no-primary-key 对INSERT语句去除主键。可选。默认False
  • -B, --flashback 生成回滚SQL,可解析大文件,不受内存限制。可选。默认False。与stop-never或no-primary-key不能同时添加。
  • --back-interval -B模式下,每打印一千行回滚SQL,加一句SLEEP多少秒,如不想加SLEEP,请设为0。可选。默认1.0。

解析范围控制:

  • --start-file 起始解析文件,只需文件名,无需全路径 。必须。
  • --start-position/--start-pos 起始解析位置。可选。默认为start-file的起始位置。
  • --stop-file/--end-file 终止解析文件。可选。默认为start-file同一个文件。若解析模式为stop-never,此选项失效。
  • --stop-position/--end-pos 终止解析位置。可选。默认为stop-file的最末位置;若解析模式为stop-never,此选项失效。
  • --start-datetime 起始解析时间,格式'%Y-%m-%d %H:%M:%S'。可选。默认不过滤。
  • --stop-datetime 终止解析时间,格式'%Y-%m-%d %H:%M:%S'。可选。默认不过滤。

对象过滤:

  • -d, --databases 只解析目标db的sql,多个库用空格隔开,如-d db1 db2。可选。默认为空。
  • -t, --tables 只解析目标table的sql,多张表用空格隔开,如-t tbl1 tbl2。可选。默认为空。
  • --only-dml 只解析dml,忽略ddl。可选。默认False。
  • --sql-type 只解析指定类型,支持INSERT, UPDATE, DELETE。多个类型用空格隔开,如--sql-type INSERT DELETE。可选。默认为增删改都解析。用了此参数但没填任何类型,则三者都不解析。

使用案例:

案例一:解析binlog,生成正向的sql语句。

[root@localhost binlog2sql]# python2.7 binlog2sql/binlog2sql.py  -h127.0.0.1 -P3306 -uadmin -p'123456'  --start-file='mysql-bin.000001' --stop-file='mysql-bin.000001'
USE db;
create database db;
USE db;
create table tb(id int);
INSERT INTO `db`.`tb`(`id`) VALUES (100); #start 530 end 683 time  2019-09-25 11:28:26
INSERT INTO `db`.`tb`(`id`) VALUES (1); #start 779 end 925 time  2019-09-25 11:31:15
USE db;
create table tb1(id int);

在没有加 --only-dml 参数的情况下,会连ddl语句也解析出来,加上 --only-dml 参数,看到只解析dml语句。

[root@localhost binlog2sql]# python2.7 binlog2sql/binlog2sql.py  -h127.0.0.1 -P3306 -uadmin -p'123456'  --start-file='mysql-bin.000001' --stop-file='mysql-bin.000001'  --only-dml
INSERT INTO `db`.`tb`(`id`) VALUES (100); #start 530 end 683 time  2019-09-25 11:28:26
INSERT INTO `db`.`tb`(`id`) VALUES (1); #start 779 end 925 time  2019-09-25 11:31:15

案例二:解析binlog,生成回滚的sql语句。

[root@localhost binlog2sql]# python2.7 binlog2sql/binlog2sql.py  -h127.0.0.1 -P3306 -uadmin -p'123456'  --start-file='mysql-bin.000001' --stop-file='mysql-bin.000001'  --flashback
DELETE FROM `db`.`tb` WHERE `id`=1 LIMIT 1; #start 779 end 925 time  2019-09-25 11:31:15
DELETE FROM `db`.`tb` WHERE `id`=100 LIMIT 1; #start 530 end 683 time  2019-09-25 11:28:26

加上--flashback参数,即可生成回滚的sql。回滚sql是正向sql的反转,insert 100, insert 1, 反转后,变为 delete 1, delete 100。

问题:

binlog2sql解析binlog依赖于第三方开源库python-mysql-replication,这个开源库在解析不规范的时间、日期格式时会有问题,比如timestamp类型的字段,如果值为'0000-00-00 00:00:00'时,解析结果为
'1970-01-01 08:00:00',这个值无法插入到MySQL中。这样的问题很早就有人提出来了,但是官方一直拒绝修复,可能官方认为'0000-00-00 00:00:00'这样的时间戳本来就是无效的,不需要处理这样无效的值,应该修改mysql的sql_mode来避免出现这种不规范的值。

总结:

binlog2sql 安装使用方便,源码文件不多,也不大,但是功能非常强大。需要注意的是,在使用binlog2sql时,mysql server必须开启,离线模式下不能解析。

文章评论

0条评论