58到家mysqlbinlog闪回工具介绍

简介

项目地址:58daojia-dba/mysqlbinlog_flashback

目前运行情况 现在已经在阿里的rds上,db为utf8字符集的生产环境下使用。其他环境没有在生产环境下使用,请小心。

#工具简介

概述 mysqlbinlog_back.py 是在线读取row格式的mysqld的binlog,然后生成反向的sql语句的工具。一般用于数据恢复的目的。 所谓反向的sql语句就是如果是insert,则反向的sql为delete。如果delete,反向的sql是insert,如果是update, 反向的sql还是update,但是update的值是原来的值。

最简单的例子为 python mysqlbinlog_back.py --host="127.0.0.1" --username="root" --port=43306 --password="" --schema=test --table="test5"

下面是程序输出结果 ls -l log/*

1
2
3
-rw-r--r-- 1 root root 2592 Nov 9 15:44 log/save_data_dml_test_20161109_154434.sql
-rw-r--r-- 1 root root 1315 Nov 9 15:44 log/flashback_test_20161109_154434.sql <--- 反向sq文件
-rw-r--r-- 1 root root 441 Nov 9 15:44 log/save_data_create_table_test_20161109_154434.sql

它会在线连接参数指定mysql,读取binlog,仅仅抽取对schematest 表名test5的binlog,生成反向sq文件保存在log目录下,其中flash_开头的文件是反向的sql语句。

用mysql命令导入数据是一定指定字符集为utf8mb4, 比如

1
mysql ... --default-character-set=utf8mb4 test < flashback_test_20161109_154434.sql

依赖的包和环境

  • python2.6
  • pymysql

使用限制

1.支持mysql版本为MySQL 5.5 and 5.6.因为底层使用的是python-mysql-replication包。

2.数据库必须是row格式的。原因看这个链接

3.反向生成的表必须有主键。

4.日志必须在主库存在

5.反向生成的mysql数据类型列出在下面。没有列出的类型没有经过严格的测试,也许有问题

6.支持的类型

允许解析的字段类型,不在里面的会报错

ALLOW_TYPE={ “varchar”:True, “char”:True, “datetime”:True, “date”:True, “time”:True, “timestamp”:True, “bigint”:True, “mediumint”:True, “smallint”:True, “tinyint”:True, “int”:True, “smallint”:True, “decimal”:True, “float”:True, “double”:True, “longtext”:True, “tinytext”:True, “text”:True, “mediumtext”:True }

列子

  • 创建test库test表
  • INSERT,UPDATE, DELETE一定的数据
  • 执行mysqlbinlog_back.py
1
2
3
4
5
6
python mysqlbinlog_back.py --host="127.0.0.1" --username="root" --port=3306 --password="root" --schema="test" --table="test"
===log will also write to .//mysqlbinlog_flashback.log===
parameter={'start_binlog_file': u'mysql-bin.000006', 'stream': None, 'keep_data': True, 'file': {'data_create': None, 'flashback': None, 'data': None}, 'add_schema_name': False, 'start_time': None, 'keep_current_data': False, 'start_to_timestamp': None, 'mysql_setting': {'passwd': 'root', 'host': '127.0.0.1', 'charset': 'utf8', 'port': 3306, 'user': 'root'}, 'table_name': 'test', 'skip_delete': False, 'schema': 'test', 'stat': {'flash_sql': {}}, 'table_name_array': ['test'], 'one_binlog_file': False, 'output_file_path': './log', 'start_position': 4, 'skip_update': False, 'dump_event': False, 'end_to_timestamp': 1519897923.0, 'skip_insert': False, 'schema_array': ['test']}
===statistics===
scan 5650 events
{'flash_sql': {u'test': {u'test': {'insert': 1, 'update': 4, 'delete': 6}}}}
  • 查看反向sql文件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
cat log/flashback_test_20180301_175203.sql
#end_log_pos 948440 2018-03-01T17:50:17 1519897817 mysql-bin.000006;
delete from `test` where `id`=1;
#end_log_pos 948645 2018-03-01T17:50:21 1519897821 mysql-bin.000006;
delete from `test` where `id`=2;
#end_log_pos 948850 2018-03-01T17:50:26 1519897826 mysql-bin.000006;
delete from `test` where `id`=3;
#end_log_pos 949055 2018-03-01T17:50:32 1519897832 mysql-bin.000006;
delete from `test` where `id`=4;
#end_log_pos 949260 2018-03-01T17:50:36 1519897836 mysql-bin.000006;
delete from `test` where `id`=5;
#end_log_pos 949465 2018-03-01T17:50:42 1519897842 mysql-bin.000006;
delete from `test` where `id`=6;
#end_log_pos 949689 2018-03-01T17:50:58 1519897858 mysql-bin.000006;
update `test` set`username`='b',`passwd`='b',`age`=2,`id`=2 where `id`=2;
#end_log_pos 949913 2018-03-01T17:51:03 1519897863 mysql-bin.000006;
update `test` set`username`='d',`passwd`='d',`age`=4,`id`=4 where `id`=4;
#end_log_pos 950142 2018-03-01T17:51:10 1519897870 mysql-bin.000006;
update `test` set`username`='d',`passwd`='llllll',`age`=4,`id`=4 where `id`=4;
#end_log_pos 950371 2018-03-01T17:51:14 1519897874 mysql-bin.000006;
update `test` set`username`='d',`passwd`='llllll',`age`=0,`id`=4 where `id`=4;
#end_log_pos 950576 2018-03-01T17:51:22 1519897882 mysql-bin.000006;
insert into `test`(`username`,`passwd`,`age`,`id`) values('a','a',1,1);
  • 我们恢复一下update数据

只提取update数据

1
python mysqlbinlog_back.py --host="127.0.0.1" --username="root" --port=3306 --password="root" --schema="test" --table="test" -I -D

开始回滚数据

1
mysql -uroot -proot --default-character-set=utf8mb4 test < log/flashback_test_20180301_175528.sql

当前网速较慢或者你使用的浏览器不支持博客特定功能,请尝试刷新或换用Chrome、Firefox等现代浏览器