binlog2sql源码-20201020

 

 

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

 

用途

 

                                

  • 数据快速回滚(闪回)

  • 主从切换后新master丢数据的修复

  • 从binlog生成标准SQL,带来的衍生功能

 

项目状态

 

正常维护。应用于部分公司线上环境。

 

 

安装

安装方法1

 

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

shell> pip install -r requirements.txt

 

 

 

安装方法2

 

在内网环境下,可手动安装这些包,目前,这些包已下载打包,并上传到百度云盘中,大家可自行下载。

http://pan.baidu.com/s/1qYQ2PPy

 

安装教程:

[root@mysql-198 ~]# tar xvf binlog2sql.tar.gz

[root@mysql-198 ~]# cd binlog2sql/binlog2sql_dependencies/

[root@mysql-198 ~]# tar xvf setuptools-0.6c11.tar.gz

[root@mysql-198 ~]# cd setuptools-0.6c11

[root@mysql-198 ~]# python setup.py install

[root@mysql-198 ~]# cd ..

[root@mysql-198 ~]# tar xvf pip-9.0.1.tar.gz

[root@mysql-198 ~]# cd pip-9.0.1

[root@mysql-198 ~]# python setup.py install

[root@mysql-198 ~]# cd ..

[root@mysql-198 ~]# pip install *.whl mysql-replication-0.9.tar.gz

DEPRECATION: Python 2.6 is no longer supported by the Python core team, please upgrade your Python. A future version of pip will drop

support for Python 2.6Processing ./mysql-replication-0.9.tar.gz

Processing ./argparse-1.4.0-py2.py3-none-any.whl

Processing ./linecache2-1.0.0-py2.py3-none-any.whl

Requirement already satisfied: PyMySQL==0.7.8 from file:///root/binlog2sql/binlog2sql_dependencies/PyMySQL-0.7.8-py2-none-any.whl in

/usr/lib/python2.6/site-packagesProcessing ./six-1.10.0-py2.py3-none-any.whl

Processing ./traceback2-1.4.0-py2.py3-none-any.whl

Processing ./unittest2-1.1.0-py2.py3-none-any.whl

Processing ./wheel-0.24.0-py2.py3-none-any.whl

Installing collected packages: argparse, linecache2, six, traceback2, unittest2, wheel, mysql-replication

Running setup.py install for mysql-replication ... done

Successfully installed argparse-1.4.0 linecache2-1.0.0 mysql-replication-0.9 six-1.10.0 traceback2-1.4.0 unittest2-1.1.0 wheel-0.24.0

 

 

git与pip的安装问题请自行搜索解决。

 

使用

 

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

                      

建议授权

GRANT SELECT, REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO USERNAME;

 

权限

 

 

基本用法

首先确认当前使用的bin_log

 

mysql> show master status\G;

 

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

             File: log_bin.000010

         Position: 1459

     Binlog_Do_DB:

 Binlog_Ignore_DB:

Executed_Gtid_Set:

1 row in set (0.00 sec)

 

 

解析出标准SQL

 

[root@mysql-198 binlog2sql]# python binlog2sql.py -h127.0.0.1 -P3306 -uroot -p'123456' -dtest -t test01  --start-file='log_bin.000010'

 

输出:

USE test;

drop database test;

USE test;

create database test;

USE test;

create table test01(n1 date);

INSERT INTO `test`.`test01`(`n1`) VALUES ('2019-02-15'); #start 652 end 890 time 2019-02-15 10:04:02

INSERT INTO `test`.`test01`(`n1`) VALUES ('2019-02-15'); #start 921 end 1159 time 2019-02-15 10:04:10

INSERT INTO `test`.`test01`(`n1`) VALUES ('2019-02-15'); #start 1190 end 1428 time 2019-02-15 10:04:13

 

 

 

 

解析出回滚SQL

 

[root@mysql-198 binlog2sql]# python binlog2sql.py --flashback -h127.0.0.1 -P3306 -uroot -p'123456' -dtest -t test01  --start-file='log_bin.000010'

 

输出:

DELETE FROM `test`.`test01` WHERE `n1`='2019-02-15' LIMIT 1; #start 1190 end 1428 time 2019-02-15 10:04:13

DELETE FROM `test`.`test01` WHERE `n1`='2019-02-15' LIMIT 1; #start 921 end 1159 time 2019-02-15 10:04:10

DELETE FROM `test`.`test01` WHERE `n1`='2019-02-15' LIMIT 1; #start 652 end 890 time 2019-02-15 10:04:02

 

 

选项

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。可选。默认为增删改都解析。用了此参数但没填任何类型,则三者都不解析。

 

应用案例

误删整张表数据,需要紧急回滚

闪回详细介绍可参见example目录下《闪回原理与实战》example/mysql-flashback-priciple-and-practice.md

test库 test01 表原有数据

mysql> select * from test01;

 

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

| n1         |

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

| 2019-02-15 |

| 2019-02-15 |

| 2019-02-15 |

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

3 rows in set (0.00 sec)

 

mysql> delete from test01;

Query OK, 3 rows affected (0.00 sec)

 

20:28时,tbl表误操作被清空

mysql> select * from test01;

Empty set (0.00 sec)

 

恢复数据步骤:

  1. 登录mysql,查看目前的binlog文件

mysql> show master status;

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

| File           | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |

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

| log_bin.000010 |     1728 |              |                  |                   |

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

1 row in set (0.00 sec)

 

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

 

[root@mysql-198 binlog2sql]# python binlog2sql.py -h127.0.0.1 -P3306 -uroot -p'123456' -dtest -t test01  --start-file='log_bin.000010'  --start-datetime='2019-02-15 10:00:00' --stop-datetime='2019-02-15 10:25:00'

 

输出结果

DELETE FROM `test`.`test01` WHERE `n1`='2019-02-15' LIMIT 1; #start 1459 end 1697 time 2019-02-15 10:19:44

DELETE FROM `test`.`test01` WHERE `n1`='2019-02-15' LIMIT 1; #start 1459 end 1697 time 2019-02-15 10:19:44

DELETE FROM `test`.`test01` WHERE `n1`='2019-02-15' LIMIT 1; #start 1459 end 1697 time 2019-02-15 10:19:44

 

 

 

  1. 我们得到了误操作sql的准确位置在1459 -1697 之间,再根据位置进一步过滤,使用flashback模式生成回滚sql,检查回滚sql是否正确(注:真实环境下,此步经常会进一步筛选出需要的sql。结合grep、编辑器等)

 

[root@mysql-198 binlog2sql]# python binlog2sql.py -h127.0.0.1 -P3306 -uroot -p'123456' -dtest -ttest01 --start-file='log_bin.000010' --start-position=1459 --stop-position=1697 -B  >rollback.sql

 

INSERT INTO `test`.`test01`(`n1`) VALUES ('2019-02-15'); #start 1459 end 1697 time 2019-02-15 10:19:44

INSERT INTO `test`.`test01`(`n1`) VALUES ('2019-02-15'); #start 1459 end 1697 time 2019-02-15 10:19:44

INSERT INTO `test`.`test01`(`n1`) VALUES ('2019-02-15'); #start 1459 end 1697 time 2019-02-15 10:19:44

 

 

 

  1. 确认回滚sql正确,执行回滚语句。登录mysql确认,数据回滚成功。

 

mysql> source /scripts/binlog2sql/binlog2sql/rollback.sql

 

Query OK, 1 row affected (0.05 sec)

 

Query OK, 1 row affected (0.00 sec)

 

Query OK, 1 row affected (0.01 sec)

 

 

mysql> select * from test01;

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

| n1         |

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

| 2019-02-15 |

| 2019-02-15 |

| 2019-02-15 |

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

3 rows in set (0.00 sec)

  1.  

限制(对比mysqlbinlog)

  • mysql server必须开启,离线模式下不能解析

  • 参数 binlog_row_image 必须为FULL,暂不支持MINIMAL

  • 解析速度不如mysqlbinlog

 

优点(对比mysqlbinlog)

  • 纯Python开发,安装与使用都很简单

  • 自带flashback、no-primary-key解析模式,无需再装补丁

  • flashback模式下,更适合闪回实战

  • 解析为标准SQL,方便理解、筛选

  • 代码容易改造,可以支持更多个性化解析

 

贡献者

联系我

有任何问题,请与我联系。邮箱:danfengcao.info@gmail.com

欢迎提问题提需求,欢迎pull requests!

 

 

源文档 <https://github.com/danfengcao/binlog2sql>

创建时间:2021-12-22 09:18
浏览量:0