在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
开源软件名称:bin2sql开源软件地址:https://gitee.com/succy/bin2sql开源软件介绍:MySQL binlog转Sql工具简介工具起源 一开始,我只想找一个工具去解析mysql的binlog,以便于不时之需恢复数据,首当其冲肯定是想到mysql官方都提供了哪些,因此最开始是研究mysqlbinlog这个工具的,但是后面发现,它只能指定到database级别,并不能到table级别,而且有时候我们不是很关心create/drop之类的sql,比较关心DML,甚至关心我能不能只过滤出来指定的表指定的类型的SQL语句。也正是由于这个原因,我在网上寻找了很多这方便的工具,总结一下网上的工具主要都是如下两方面的: 1、通过伪装成slave拉取binlog来进行处理。以binlog2sql为代表. 2、直接解析binlog文件,然后对数据做二次过滤的,以mysqlbinlog和本程序为代表。 然而binlog2sql在我使用过程中,总得来说也还不错的,就是其运行有点慢,我就想能不能有一个工具可以直接解析binlog又能满足我的要求的?寻求了一圈之后我发现并没有很符合我的要求的,于是我打算自己写一个。一开始我并不打算使用Perl语言写的,因为我对这个语言不是很熟悉,我是想着用go或者python写的,但是在我用go和python写了一段时间之后,都发现在处理文本这块有些许不足,可能也是因为我的水平问题吧,因此我选择了Perl语言,简单看了下语法和网上的一些案例之后,就开始写了,Perl同时有着强大的正则表达式和能直接运行shell命令的强大特点让我在编写过程中节约了很多时间。 这个小工具采用了mysqlbinlog作为主要产生数据的工具,通过Perl调用mysqlbinlog获取到可读的binlog数据,然后再进行流式处理,从而达到目的,在目前我的使用过程中发现,这样的配合执行速度还是不错的。由于我的Perl水平实在是有限,程序也难免会有错误,如果发现有错误或者有更好的写法,欢迎issue和pr或者直接邮件联系本人 功能介绍这是一款使用perl语言开发的mysql binlog转sql的工具,主要是弥补了
设计思路整个脚本设计思路非常简单,大致分为三步 1、通过操作指定的数据源,获取到information_schema存储的表字段信息。 2、通过mysqlbinlog工具,获取指定binlog文件。 3、解析binlog,提取出来sql,替换占位符为字段名,还原SQL,通过反转SQL,起到闪回的目的。 经过本人实践,依托Perl和mysqlbinlog,其性能还是不错的,整个过程都是使用流式处理的,理论上可以应对比较大的binlog文件,但是本人公司内毕竟需要恢复数据的场景并不是那么多(如果非常多误操作,怕是饭碗不保了),因此可能有些地方会略为片面,有需要的可以自行进行测试和修改或者提ISSUE。 注意事项这里的内容非常关键,请务必注意 Q:如果我把表删了,还能恢复数据吗? A:如果你把表删了,有备份在,并且表结构也没发生变化,可以恢复的。 Q:我就是把表删了,但是没有重建表结构,能把这个表之前发生的SQL操作恢复吗? A:不可以。因为我们依赖 Q:如果表结构发生了变化,能恢复吗? A:不能,都改表了,你恢复以前的数据有什么意义?就算强行解析出来,可能都错位了或者这个SQL就是有问题的了 安装和配置
免安装版本直接到release下载可执行文件,到Linux系统,添加可执行权限就可以运行了 源码安装首先说明一下,我都是在Linux下测试的,并且也是针对Linux环境开发的,因为Perl语言在很多Linux发行版都内置,我所使用的是CentOS7,内置的Perl是5.16.3,如果想要在Windows下使用,请安装Perl语言环境,并且修改内部的mysqlbinlog为mysqlbinlog.exe(前提是mysqlbinlog.exe在环境变量内)。
我测试的Mysql数据库版本是5.7.25 理论上>=5.6的版本都支持。不过我没有做过测试 下面是安装步骤: 1、安装DBI/DBD由于row模式下,记录了更新前后的数据,并且没有记录表的字段名,都是使用 在CentOS7下面,关于安装 1、通过yum安装cpan(cpan是Perl的一个包管理工具,类似nodejs的npm,python的pip)yum -y install cpan2、通过cpan安装DBI,如果是第一次使用cpan,会有一些配置的选项需要询问配置,此时,全部默认即可cpan install DBI3、通过cpan安装DBD:mysqlcpan install DBD::mysql 2、克隆项目并授权执行1、克隆本项目到服务器本地2、进入项目根目录并且授予可执行权限cd bin2sql && chmod +x bin2sql3、运行bin2sql 直接运行bin2sql会出现如下的帮助文档 MySQL Binlog to SQLOptions: -h, --host=name Get the binlog from server, default localhost. -u, --user=name Connect to the remote server as username, default root. -P, --port=# Port number to use for connection or 3306 for default to. -p, --password[=name] Password to connect to remote server. -t, --tables=name Export tables in table names, delimiter by comma. -d, --database=name List entries for just this database (local log only). -B, --flashback Is print flashback SQL, only DML could be flashback. --start-datetime=name Start reading the binlog at first event having a datetime equal or posterior to the argument; the argument must be a date and time in the local time zone, in any format accepted by the MySQL server for DATETIME and TIMESTAMP types, for example: 2004-12-25 11:25:56 (you should probably use quotes for your shell to set it properly). --start-position=# Start reading the binlog at position N. Applies to the first binlog passed on the command line. --stop-datetime=name Stop reading the binlog at first event having a datetime equal or posterior to the argument; the argument must be a date and time in the local time zone, in any format accepted by the MySQL server for DATETIME and TIMESTAMP types, for example: 2004-12-25 11:25:56 (you should probably use quotes for your shell to set it properly). --stop-position=# Stop reading the binlog at position N. Applies to the last binlog passed on the command line. --only-dml Only print dml sql, optional, default disabled. --sql-type Sql type you want to process, support INSERT, UPDATE, DELETE. -f, --binlog=name Read from binlog file. --help Print help message. 3、作者建议如果数据库服务器有多台的话,建议在一台空的服务器运行本脚本,通过设定-h参数远程抓去binlog解析即可,不要随意放在数据库服务器上面运行,其原因有2
用法和示例1、用法选项mysql相关连接配置
-h host; -P port; -u user; -p password这几个参数都是给mysqlbinlog使用的,这里强调一个参数,就是-u这个参数,必须拥有 REPLICATION SLAVE 权限。建议授权如下GRANT SELECT, REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO User 对象过滤-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。可选。默认为增删改都解析。 范围解析
-f,--binlog 要解析的Binlog文件名,无需全路径 。必须。--start-position 起始解析位置。可选。--stop-position 终止解析位置。可选。--start-datetime 起始解析时间,格式'%Y-%m-%d %H:%M:%S'。可选。默认不过滤。--stop-datetime 终止解析时间,格式'%Y-%m-%d %H:%M:%S'。可选。默认不过滤。 闪回-B, --flashback 生成回滚SQL,可选,默认为false,只有DML才支持闪回,DDL不支持闪回。 2、示例创建示例表CREATE TABLE `user` ( `id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'ID', `username` varchar(255) DEFAULT NULL COMMENT '用户名', `address` varchar(255) DEFAULT NULL COMMENT '地址', `create_time` datetime DEFAULT NULL COMMENT '创建时间', `phone_no` varchar(255) DEFAULT NULL COMMENT '电话号码', PRIMARY KEY (`id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; 查看表原有数据mysql> select * from user;+----+-----------+-----------------+---------------------+--------------+| id | username | address | create_time | phone_no |+----+-----------+-----------------+---------------------+--------------+| 1 | Succy | 广西南宁市 | 2021-05-03 21:05:14 | 1300000001 || 2 | 王小花 | 山西太原市 | 2021-05-03 21:05:46 | 15099999999 || 3 | 江小白 | 重庆市 | 2021-05-03 21:06:21 | 19788888888 || 4 | 郭靖 | 湖北襄阳 | 2021-05-03 21:06:43 | 188888898999 || 5 | 杨过 | 江苏苏州 | 2021-05-03 21:07:10 | 16666666878 || 6 | 陆无双 | 山东济南市 | 2021-05-03 21:07:35 | 155236995454 |+----+-----------+-----------------+---------------------+--------------+6 rows in set (0.00 sec)
解析出user表所有操作的sqlshell> ./bin2sql -d demo -f mysql-bin.000002 -h 127.0.0.1 -t user#210503 21:03:54 end_log_pos: 7852CREATE TABLE `demo`.`user` ( `id` int(0) NOT NULL AUTO_INCREMENT COMMENT 'ID', `username` varchar(255) NULL COMMENT '用户名', `address` varchar(255) NULL COMMENT '地址', `create_time` datetime(0) NULL COMMENT '创建时间', `phone_no` varchar(255) NULL COMMENT '电话号码', PRIMARY KEY (`id`));#210503 21:05:24 end_log_pos: 8128INSERT INTO `demo`.`user` VALUES(1, 'Succy', '广西南宁市', '2021-05-03 21:05:14', '1300000001');#210503 21:05:53 end_log_pos: 8440INSERT INTO `demo`.`user` VALUES(2, '王小花', '山西太原市', '2021-05-03 21:05:46', '15099999999');#210503 21:06:27 end_log_pos: 8746INSERT INTO `demo`.`user` VALUES(3, '江小白', '重庆市', '2021-05-03 21:06:21', '19788888888');#210503 21:06:50 end_log_pos: 9053INSERT INTO `demo`.`user` VALUES(4, '郭靖', '湖北襄阳', '2021-05-03 21:06:43', '188888898999');#210503 21:07:14 end_log_pos: 9359INSERT INTO `demo`.`user` VALUES(5, '杨过', '江苏苏州', '2021-05-03 21:07:10', '16666666878');#210503 21:07:44 end_log_pos: 9672INSERT INTO `demo`.`user` VALUES(6, '陆无双', '山东济南市', '2021-05-03 21:07:35', '155236995454');#210503 21:10:45 end_log_pos: 10030UPDATE `demo`.`user` SET `id`=5, `username`='杨过过', `address`='江苏南京市', `create_time`='2021-05-03 21:07:10', `phone_no`='16666666878' WHERE `id`=5 AND `username`='杨过' AND `address`='江苏苏州' AND `create_time`='2021-05-03 21:07:10' AND `phone_no`='16666666878';#210503 21:11:07 end_log_pos: 10340INSERT INTO `demo`.`user` VALUES(7, '公孙绿萼', '绝情谷', '2021-05-03 21:11:01', '188777738934');#210503 21:11:30 end_log_pos: 10645INSERT INTO `demo`.`user` VALUES(8, '程英', '桃花岛', '2021-05-03 21:11:24', '1778346836483');#210503 21:11:33 end_log_pos: 10951DELETE FROM `demo`.`user` WHERE `id`=3 AND `username`='江小白' AND `address`='重庆市' AND `create_time`='2021-05-03 21:06:21' AND `phone_no`='19788888888';#210503 21:11:51 end_log_pos: 11315UPDATE `demo`.`user` SET `id`=2, `username`='王小花', `address`='广东深圳市', `create_time`='2021-05-03 21:05:46', `phone_no`='15099999999' WHERE `id`=2 AND `username`='王小花' AND `address`='山西太原市' AND `create_time`='2021-05-03 21:05:46' AND `phone_no`='15099999999';
闪回所有误操作的数据shell> ./bin2sql -d demo -f mysql-bin.000002 -h 127.0.0.1 -t user -B --sql-type DELETE,UPDATE#210503 21:10:45 end_log_pos: 10030UPDATE `demo`.`user` SET `id`=5, `username`='杨过', `address`='江苏苏州', `create_time`='2021-05-03 21:07:10', `phone_no`='16666666878' WHERE `id`=5 AND `username`='杨过过' AND `address`='江苏南京市' AND `create_time`='2021-05-03 21:07:10' AND `phone_no`='16666666878';#210503 21:11:33 end_log_pos: 10951INSERT INTO `demo`.`user` VALUES(3, '江小白', '重庆市', '2021-05-03 21:06:21', '19788888888');#210503 21:11:51 end_log_pos: 11315UPDATE `demo`.`user` SET `id`=2, `username`='王小花', `address`='山西太原市', `create_time`='2021-05-03 21:05:46', `phone_no`='15099999999' WHERE `id`=2 AND `username`='王小花' AND `address`='广东深圳市' AND `create_time`='2021-05-03 21:05:46' AND `phone_no`='15099999999'; 更多玩法等着你去发掘 鸣谢binlog2sql 这个项目给我提供了我python版本的借鉴,虽然后面python版本的流产了。 MySQL_Binlog_Table_Filter 本工具借鉴了这个项目,由于我是Perl新手,这个项目给我提供了不少Perl相关写法借鉴。 |
请发表评论