MySQL闪回工具之my2sql

my2sql是一个用Go语言编写的MySQL binlog解析工具,能够生成原始SQL、回滚SQL等,并提供DML统计信息。在误删数据时,它能帮助紧急回滚。使用时,binlog格式需为row且binlog_row_image=full。my2sql具备丰富的功能,包括回滚、DML统计等,并且解析速度较快。

my2sql

简介

go版MySQL binlog解析工具,通过解析MySQL binlog ,可以生成原始SQL、回滚SQL、去除主键的INSERT SQL等,也可以生成DML统计信息。https://github.com/liuhr/my2sql

安装

编译

git clone https://github.com/liuhr/my2sql.git
cd my2sql/
go build .

也可以直接下载Linux版编译好的可执行文件
https://github.com/liuhr/my2sql/blob/master/releases/my2sql

应用案例

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

mysql> #数据库
mysql> show create database testdb\G
*************************** 1. row ***************************
       Database: testdb
Create Database: CREATE DATABASE `testdb` /*!40100 DEFAULT CHARACTER SET utf8mb4 */

mysql> #表结构
mysql> show create table student\G
*************************** 1. row ***************************
       Table: student
Create Table: CREATE TABLE `student` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `number` int(11) NOT NULL,
  `name` varchar(255) DEFAULT NULL,
  `add_time` timestamp NULL DEFAULT CURRENT_TIMESTAMP COMMENT '添加的时间',
  `content` json DEFAULT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `idx_name` (`number`,`name`)
) ENGINE=InnoDB AUTO_INCREMENT=1234 DEFAULT CHARSET=utf8

mysql> #数据
mysql> select * from student;
+------+--------+---------+---------------------+---------------------------------+
| id   | number | name    | add_time            | content                         |
+------+--------+---------+---------------------+---------------------------------+
|   12 |     12 | che     | 2020-07-06 19:39:17 | NULL                            |
| 1217 |     12 | hanraan | 2020-07-06 19:39:17 | NULL                            |
| 1218 |     12 | NULL    | 2020-07-06 19:39:17 | NULL                            |
| 1219 |     12 | hanran  | 2020-07-06 19:39:17 | NULL                            |
| 1221 |     13 | hanran  | 2020-07-06 19:40:10 | NULL                            |
| 1222 |     14 | hanran  | 2020-07-06 19:42:17 | NULL                            |
| 1223 |     15 | hanran  | 2020-07-06 21:55:48 | {"author": "liuhan"}            |
| 1224 |     16 | hanran  | 2020-07-06 21:55:48 | {"author": "liuhan"}            |
| 1226 |     17 | hanran  | 2020-07-06 21:55:48 | {"age": 13, "author": "liuhan"} |
| 1227 |     18 | hanran  | 2020-07-06 21:55:48 | {"age": 13, "author": "liuhan"} |
| 1229 |     20 | chenxi  | 2020-07-11 16:20:50 | NULL                            |
| 1231 |     21 | chenxi  | 2020-07-12 10:12:45 | NULL                            |
| 1232 |    134 | asdf    | 2020-07-12 11:08:41 | NULL                            |
| 1233 |     26 | ranran  | 2020-07-15 19:06:03 | NULL                            |
+------+--------+---------+---------------------+---------------------------------+

mysql> #为了方便演示,重新生成一个binlog
mysql> flush logs;

mysql> #删除表数据
mysql> delete from student;
Query OK, 14 rows affected (0.05 sec)

mysql> select * from student;
Empty set (0.00 sec)

查看binlog文件

mysql> show master status;
+------------------+----------+--------------+------------------+-------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000045 |      837 |              |                  |                   |
+------------------+----------+--------------+------------------+-------------------+

根据操作时间解析binlog,生成回滚日志

./my2sql  -user root -password 123456  -port 3306 \
-host 127.0.0.1 -databases testdb  -tables student \
-work-type rollback   -start-file mysql-bin.000045 \
-start-datetime "2020-07-18 11:40:00" --stop-datetime "2020-07-18 12:00:00" \
-output-dir tmpdir/

查看生成的回滚SQL

cd tmpdir/
ls
biglong_trx.txt		binlog_status.txt	rollback.45.sql

#查看DML信息
cat binlog_status.txt
binlog            starttime           stoptime            startpos   stoppos    inserts  updates  deletes  database        table
mysql-bin.000045  2020-07-18_11:49:53 2020-07-18_11:49:53 293        806        0        0        14       testdb          student
#上面信息可以看到解析的binlog DML情况

#查看回滚SQL
cat rollback.45.sql
INSERT INTO `testdb`.`student` (`id`,`number`,`name`,`add_time`,`content`) VALUES (1233,26,'ranran','2020-07-15 19:06:03',null);
INSERT INTO `testdb`.`student` (`id`,`number`,`name`,`add_time`,`content`) VALUES (1232,134,'asdf','2020-07-12 11:08:41',null);
INSERT INTO `testdb`.`student` (`id`,`number`,`name`,`add_time`,`content`) VALUES (1231,21,'chenxi','2020-07-12 10:12:45',null);
INSERT INTO `testdb`.`student` (`id`,`number`,`name`,`add_time`,`content`) VALUES (1229,20,'chenxi','2020-07-11 16:20:50',null);
INSERT INTO `testdb`.`student` (`id`,`number`,`name`,`add_time`,`content`) VALUES (1227,18,'hanran','2020-07-06 21:55:48','{\"age\":13,\"author\":\"liuhan\"}');
INSERT INTO `testdb`.`student` (`id`,`number`,`name`,`add_time`,`content`) VALUES (1226,17,'hanran','2020-07-06 21:55:48','{\"age\":13,\"author\":\"liuhan\"}');
INSERT INTO `testdb`.`student` (`id`,`number`,`name`,`add_time`,`content`) VALUES (1224,16,'hanran','2020-07-06 21:55:48','{\"author\":\"liuhan\"}');
INSERT INTO `testdb`.`student` (`id`,`number`,`name`,`add_time`,`content`) VALUES (1223,15,'hanran','2020-07-06 21:55:48','{\"author\":\"liuhan\"}');
INSERT INTO `testdb`.`student` (`id`,`number`,`name`,`add_time`,`content`) VALUES (1222,14,'hanran','2020-07-06 19:42:17',null);
INSERT INTO `testdb`.`student` (`id`,`number`,`name`,`add_time`,`content`) VALUES (1221,13,'hanran','2020-07-06 19:40:10',null);
INSERT INTO `testdb`.`student` (`id`,`number`,`name`,`add_time`,`content`) VALUES (1219,12,'hanran','2020-07-06 19:39:17',null);
INSERT INTO `testdb`.`student` (`id`,`number`,`name`,`add_time`,`content`) VALUES (1218,12,null,'2020-07-06 19:39:17',null);
INSERT INTO `testdb`.`student` (`id`,`number`,`name`,`add_time`,`content`) VALUES (1217,12,'hanraan','2020-07-06 19:39:17',null);
INSERT INTO `testdb`.`student` (`id`,`number`,`name`,`add_time`,`content`) VALUES (12,12,'che','2020-07-06 19:39:17',null);

#应用回滚SQL恢复数据
mysql -u root -p123456 -P3306 -h127.0.0.1  testdb < tmpdir/rollback.45.sql
mysql> select * from student;
+------+--------+---------+---------------------+---------------------------------+
| id   | number | name    | add_time            | content                         |
+------+--------+---------+---------------------+---------------------------------+
|   12 |     12 | che     | 2020-07-06 19:39:17 | NULL                            |
| 1217 |     12 | hanraan | 2020-07-06 19:39:17 | NULL                            |
| 1218 |     12 | NULL    | 2020-07-06 19:39:17 | NULL                            |
| 1219 |     12 | hanran  | 2020-07-06 19:39:17 | NULL                            |
| 1221 |     13 | hanran  | 2020-07-06 19:40:10 | NULL                            |
| 1222 |     14 | hanran  | 2020-07-06 19:42:17 | NULL                            |
| 1223 |     15 | hanran  | 2020-07-06 21:55:48 | {"author": "liuhan"}            |
| 1224 |     16 | hanran  | 2020-07-06 21:55:48 | {"author": "liuhan"}            |
| 1226 |     17 | hanran  | 2020-07-06 21:55:48 | {"age": 13, "author": "liuhan"} |
| 1227 |     18 | hanran  | 2020-07-06 21:55:48 | {"age": 13, "author": "liuhan"} |
| 1229 |     20 | chenxi  | 2020-07-11 16:20:50 | NULL                            |
| 1231 |     21 | chenxi  | 2020-07-12 10:12:45 | NULL                            |
| 1232 |    134 | asdf    | 2020-07-12 11:08:41 | NULL                            |
| 1233 |     26 | ranran  | 2020-07-15 19:06:03 | NULL                            |
+------+--------+---------+---------------------+---------------------------------+
14 rows in set (0.00 sec)

根据POS点解析binlog,生成回滚日志
也可以根据binlog的pos点解析,这里不在展示
执行命令:

./my2sql  -user root -password 123456  -port 3306 \
-host 127.0.0.1 -databases testdb  -tables student \
-work-type rollback   -start-file mysql-bin.000045 \
-start-pos  4 -stop-file  mysql-bin.000045 -stop-pos  837 \
-output-dir tmpdir/
总结
限制
  • 使用回滚/闪回功能时,binlog格式必须为row,且binlog_row_image=full, DML统计以及大事务分析不受影响
    只能回滚DML, 不能回滚DDL
  • 支持指定-tl时区来解释binlog中time/datetime字段的内容。开始时间-start-datetime与结束时间-stop-datetime也会使用此指定的时区, 但注意此开始与结束时间针对的是binlog event header中保存的unix timestamp。结果中的额外的datetime时间信息都是binlog event header中的unix timestamp
  • 此工具是伪装成从库拉取binlog,需要连接数据库的用户有SELECT, REPLICATION SLAVE, REPLICATION CLIENT权限
优点
  • 功能丰富,不仅支持回滚操作,还有其他实用功能。请参考之前博文
  • 基于golang实现,速度快,全量解析1.1Gbinlog只需要1分30秒左右,当前其他类似开源工具一般要几十分钟
  • github地址 https://github.com/liuhr/my2sql (好使的话别忘记给个星哦😄)

my2sql功能介绍相关博文

MySQL binlog回滚/闪回、前滚、DML统计、长事务与大事务分析
https://blog.youkuaiyun.com/liuhanran/article/details/107425016

MySQL 解析binlog生成标准SQL工具之my2sql
https://blog.youkuaiyun.com/liuhanran/article/details/107427204

MySQL 解析binlog 统计DML、长事务与大事务分析工具之my2sql
https://blog.youkuaiyun.com/liuhanran/article/details/107427391

评论 4
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值