MySQL闪回-binlog2sql
发布日期:2021-11-08 09:37:38 浏览次数:1 分类:技术文章

本文共 5492 字,大约阅读时间需要 18 分钟。



参考:    

 

binlog2sql

 

从mysql binlog解析出你要的sql。根据不同选项,你可以得到原始sql、回滚sql、去除主键的insert sql等。

 

用途

  • 数据快速回滚(闪回)
  • 主从切换后数据不一致的修复
  • 从binlog生成标准SQL,带来的衍生功能

 

 

项目状态

 

•已测试环境 Python 2.6, 2.7

•MySQL 5.6,5.7

 

 

工具安装

 

git clone https://github.com/danfengcao/binlog2sql.git && cd binlog2sql

pip install -r requirements.txt

 

需要先安装 git 和 pip

yum -y install git 

yum -y install epel-release 

yum -y install python-pip

安装 PyMySQL

pip install PyMySQL

 

mysql server必须设置以下参数:

[mysqld]

server_id = 1

log_bin = /var/log/mysql/mysql-bin.log

max_binlog_size = 1g

binlog_format = row

binlog_row_image = full

 

user需要的最小权限集合:

select, super/replication client, replication slave

 

建议授权

 

权限说明

•select:需要读取server端information_schema.columns表,获取表结构的元信息,拼接成可视化的sql语句

•super/replication client:两个权限都可以,需要执行'show master status', 获取server端的binlog列表

•replication slave:通过binlog_dump协议获取binlog内容的权限

 

解析出标准sql

 

[root@node2 binlog2sql]# python binlog2sql.py -h127.0.0.1 -P3307 -uroot -p'123456' -ddb1 -t t1 --start-file='mysql-bin.000006';

insert into `db1`.`t1`(`id`, `name`) values (5, 'java'); #start 1543 end 1691 time 2017-03-20 14:26:42

insert into `db1`.`t1`(`id`, `name`) values (6, 'php'); #start 1779 end 1934 time 2017-03-20 14:28:10

 

#选项 mysql连接配置

 

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

 

解析模式

 

--stop-never 持续同步binlog。可选。不加则同步至执行命令时最新的binlog位置。

-K, --no-primary-key 对INSERT语句去除主键。可选。

-B, --flashback 生成回滚语句,可解析大文件,不受内存限制,每打印一千行加一句SLEEP SELECT(1)。可选。与stop-never或no-primary-key不能同时添加。

 

解析范围控制

 

--start-file 起始解析文件。必须。

--start-position/--start-pos start-file的起始解析位置。可选。默认为start-file的起始位置。

--stop-file/--end-file 末尾解析文件。可选。默认为start-file同一个文件。若解析模式为stop-never,此选项失效。

--stop-position/--end-pos stop-file的末尾解析位置。可选。默认为stop-file的最末位置;若解析模式为stop-never,此选项失效。

--start-datetime 从哪个时间点的binlog开始解析,格式必须为datetime,如'2016-11-11 11:11:11'。可选。默认不过滤。

--stop-datetime 到哪个时间点的binlog停止解析,格式必须为datetime,如'2016-11-11 11:11:11'。可选。默认不过滤。

 

对象过滤

 

-d, --databases 只输出目标db的sql。可选。默认为空。

-t, --tables 只输出目标tables的sql。可选。默认为空。

 

 

删除t1表所有的数据,紧急恢复

 

mysql> delete from t1;

Query OK, 6 rows affected (0.15 sec)

 

mysql> select * from t1;

Empty set (0.00 sec)

 

 

登陆mysql

mysql> show master status\G

*************************** 1. row ***************************

             File: mysql-bin.000006

         Position: 2832

     Binlog_Do_DB: 

 Binlog_Ignore_DB: 

Executed_Gtid_Set: 3db33b36-0e51-409f-a61d-c99756e90155:1-25:1000022,

8772e43a-0ae2-11e7-aa23-005056aaa05e:1-4,

cad45731-0aea-11e7-92ce-005056aa8034:1-4

1 row in set (0.00 sec)

 

最新的binlog文件是mysql-bin.000006,我们再定位误操作SQL的binlog位置。误操作人只能知道大致的误操作时间,我们根据大致时间过滤数据。

 

[root@node2 binlog2sql]# python binlog2sql.py -h127.0.0.1 -P3307 -uroot -p'123456' -ddb1 -t t1 --start-file='mysql-bin.000006'

insert into `db1`.`t1`(`id`, `name`) values (5, 'java'); #start 1543 end 1691 time 2017-03-20 14:26:42

insert into `db1`.`t1`(`id`, `name`) values (6, 'php'); #start 1779 end 1934 time 2017-03-20 14:28:10

delete from `db1`.`t1` where `id`=1 and `name`='aaa' limit 1; #start 2604 end 2805 time 2017-03-27 15:19:29

delete from `db1`.`t1` where `id`=2 and `name`='bbb' limit 1; #start 2604 end 2805 time 2017-03-27 15:19:29

delete from `db1`.`t1` where `id`=3 and `name`='ccc' limit 1; #start 2604 end 2805 time 2017-03-27 15:19:29

delete from `db1`.`t1` where `id`=4 and `name`='ddd' limit 1; #start 2604 end 2805 time 2017-03-27 15:19:29

delete from `db1`.`t1` where `id`=5 and `name`='java' limit 1; #start 2604 end 2805 time 2017-03-27 15:19:29

delete from `db1`.`t1` where `id`=6 and `name`='php' limit 1; #start 2604 end 2805 time 2017-03-27 15:19:29

 

 

[root@node2 binlog2sql]#  python binlog2sql.py --flashback -h127.0.0.1 -P3307 -uroot -p'123456' -ddb1 -t t1 --start-file='mysql-bin.000006'

insert into `db1`.`t1`(`id`, `name`) values (6, 'php'); #start 347 end 548 time 2017-03-27 15:45:31

insert into `db1`.`t1`(`id`, `name`) values (5, 'java'); #start 347 end 548 time 2017-03-27 15:45:31

insert into `db1`.`t1`(`id`, `name`) values (4, 'ddd'); #start 347 end 548 time 2017-03-27 15:45:31

insert into `db1`.`t1`(`id`, `name`) values (3, 'ccc'); #start 347 end 548 time 2017-03-27 15:45:31

insert into `db1`.`t1`(`id`, `name`) values (2, 'bbb'); #start 347 end 548 time 2017-03-27 15:45:31

insert into `db1`.`t1`(`id`, `name`) values (1, 'aaa'); #start 347 end 548 time 2017-03-27 15:45:31

 

全部将 delete 转换成了insert

 

 

 

我们得到了误操作sql的准确位置在 2604 - 2805 之间,再根据位置进一步过滤,使用flashback模式生成回滚sql,检查回滚sql是否正确

(注:真实环境下,此步经常会进一步筛选出需要的sql。结合grep、编辑器等)

 

[root@node2 binlog2sql]# python binlog2sql.py -h127.0.0.1 -P3307 -uroot -p'123456' -ddb1 -t t1 --start-file='mysql-bin.000005'

use mysql;

flush privileges;

alter user 'root'@'localhost' identified with 'mysql_native_password' as '*6bb4837eb74329105ee4568dda7dc67ed2ca2ad9';

flush privileges;

use db1;

create database db1;

use db1;

create table t1( id int not null, name varchar(20), primary key (id) );

insert into `db1`.`t1`(`id`, `name`) values (1, 'aaa'); #start 2129 end 2271 time 2017-03-17 15:55:34

insert into `db1`.`t1`(`id`, `name`) values (2, 'bbb'); #start 2359 end 2501 time 2017-03-17 15:55:41

insert into `db1`.`t1`(`id`, `name`) values (3, 'ccc'); #start 2589 end 2731 time 2017-03-17 15:55:54

insert into `db1`.`t1`(`id`, `name`) values (4, 'ddd'); #start 2819 end 2961 time 2017-03-17 15:56:01

 

可以把 mysql-bin.000005 和 mysql-bin.000006 里面的关于t1表的操作sql合并一下合并到 backup.sql里面

 

 

[root@node2 binlog2sql]# mysql -S /tmp/mysql3307.sock -uroot -p < backup.sql 

Enter password: 

 

 

mysql> select * from t1;

+----+------+

| id | name |

+----+------+

|  1 | aaa  |

|  2 | bbb  |

|  3 | ccc  |

|  4 | ddd  |

|  5 | java |

|  6 | php  |

+----+------+

6 rows in set (0.00 sec)

 

转载地址:https://blog.csdn.net/zhengwei125/article/details/66972648 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:Innodb 表空间传输迁移大表
下一篇:django快速搭建blog系统

发表评论

最新留言

路过按个爪印,很不错,赞一个!
[***.219.124.196]2024年03月28日 00时15分51秒