数据库误删除数据库恢复工具binlog2sql,my2sql ,MyFlash,my2fback及工具使用

1、工具binlog2sql使用:

已测试环境(此工具使用时字段多时有时候存在字段和字段值不配的情况,如是生产环境,建议测试环境先查看后再导入生产)
* Python 2.7, 3.4+
* MySQL 5.6, 5.7

安装
==============

shell> git clone https://github.com/danfengcao/binlog2sql.git && cd binlog2sql
shell> pip install -r requirements.txt

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

**权限说明**

* select:需要读取server端information_schema.COLUMNS表,获取表结构的元信息,拼接成可视化的sql语句
* super/replication client:两个权限都可以,需要执行'SHOW MASTER STATUS', 获取server端的binlog列表
* replication slave:通过BINLOG_DUMP协议获取binlog内容的权限


### 基本用法


**解析出标准SQL**

```bash
shell> python binlog2sql.py -h127.0.0.1 -P3306 -uadmin -p'admin' -dtest -t test3 test4 --start-file='mysql-bin.000002'

输出:
INSERT INTO `test`.`test3`(`addtime`, `data`, `id`) VALUES ('2016-12-10 13:03:38', 'english', 4); #start 570 end 736
UPDATE `test`.`test3` SET `addtime`='2016-12-10 12:00:00', `data`='中文', `id`=3 WHERE `addtime`='2016-12-10 13:03:22' AND `data`='中文' AND `id`=3 LIMIT 1; #start 763 end 954
DELETE FROM `test`.`test3` WHERE `addtime`='2016-12-10 13:03:38' AND `data`='english' AND `id`=4 LIMIT 1; #start 981 end 1147
```

**解析出回滚SQL**

```bash

shell> python binlog2sql.py --flashback -h127.0.0.1 -P3306 -uadmin -p'admin' -dtest -ttest3 --start-file='mysql-bin.000002' --start-position=763 --stop-position=1147

输出:
INSERT INTO `test`.`test3`(`addtime`, `data`, `id`) VALUES ('2016-12-10 13:03:38', 'english', 4); #start 981 end 1147
UPDATE `test`.`test3` SET `addtime`='2016-12-10 13:03:22', `data`='中文', `id`=3 WHERE `addtime`='2016-12-10 12:00:00' AND `data`='中文' AND `id`=3 LIMIT 1; #start 763 end 954
```

### 选项

**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](./example/mysql-flashback-priciple-and-practice.md)

```bash
test库tbl表原有数据
mysql> select * from tbl;
+----+--------+---------------------+
| id | name | addtime |
+----+--------+---------------------+
| 1 | 小赵 | 2016-12-10 00:04:33 |
| 2 | 小钱 | 2016-12-10 00:04:48 |
| 3 | 小孙 | 2016-12-13 20:25:00 |
| 4 | 小李 | 2016-12-12 00:00:00 |
+----+--------+---------------------+
4 rows in set (0.00 sec)

mysql> delete from tbl;
Query OK, 4 rows affected (0.00 sec)

20:28时,tbl表误操作被清空
mysql> select * from tbl;
Empty set (0.00 sec)
```

**恢复数据步骤**:

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

```bash
mysql> show master status;
+------------------+-----------+
| Log_name | File_size |
+------------------+-----------+
| mysql-bin.000051 | 967 |
| mysql-bin.000052 | 965 |
+------------------+-----------+
```

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

```bash
shell> python binlog2sql/binlog2sql.py -h127.0.0.1 -P3306 -uadmin -p'admin' -dtest -ttbl --start-file='mysql-bin.000052' --start-datetime='2016-12-13 20:25:00' --stop-datetime='2016-12-13 20:30:00'
输出:
INSERT INTO `test`.`tbl`(`addtime`, `id`, `name`) VALUES ('2016-12-13 20:26:00', 4, '小李'); #start 317 end 487 time 2016-12-13 20:26:26
UPDATE `test`.`tbl` SET `addtime`='2016-12-12 00:00:00', `id`=4, `name`='小李' WHERE `addtime`='2016-12-13 20:26:00' AND `id`=4 AND `name`='小李' LIMIT 1; #start 514 end 701 time 2016-12-13 20:27:07
DELETE FROM `test`.`tbl` WHERE `addtime`='2016-12-10 00:04:33' AND `id`=1 AND `name`='小赵' LIMIT 1; #start 728 end 938 time 2016-12-13 20:28:05
DELETE FROM `test`.`tbl` WHERE `addtime`='2016-12-10 00:04:48' AND `id`=2 AND `name`='小钱' LIMIT 1; #start 728 end 938 time 2016-12-13 20:28:05
DELETE FROM `test`.`tbl` WHERE `addtime`='2016-12-13 20:25:00' AND `id`=3 AND `name`='小孙' LIMIT 1; #start 728 end 938 time 2016-12-13 20:28:05
DELETE FROM `test`.`tbl` WHERE `addtime`='2016-12-12 00:00:00' AND `id`=4 AND `name`='小李' LIMIT 1; #start 728 end 938 time 2016-12-13 20:28:05
```

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

```bash
shell> python binlog2sql/binlog2sql.py -h127.0.0.1 -P3306 -uadmin -p'admin' -dtest -ttbl --start-file='mysql-bin.000052' --start-position=3346 --stop-position=3556 -B > rollback.sql | cat
输出:
INSERT INTO `test`.`tbl`(`addtime`, `id`, `name`) VALUES ('2016-12-12 00:00:00', 4, '小李'); #start 728 end 938 time 2016-12-13 20:28:05
INSERT INTO `test`.`tbl`(`addtime`, `id`, `name`) VALUES ('2016-12-13 20:25:00', 3, '小孙'); #start 728 end 938 time 2016-12-13 20:28:05
INSERT INTO `test`.`tbl`(`addtime`, `id`, `name`) VALUES ('2016-12-10 00:04:48', 2, '小钱'); #start 728 end 938 time 2016-12-13 20:28:05
INSERT INTO `test`.`tbl`(`addtime`, `id`, `name`) VALUES ('2016-12-10 00:04:33', 1, '小赵'); #start 728 end 938 time 2016-12-13 20:28:05
```

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

```bash
shell> mysql -h127.0.0.1 -P3306 -uadmin -p'admin' < rollback.sql

mysql> select * from tbl;
+----+--------+---------------------+
| id | name | addtime |
+----+--------+---------------------+
| 1 | 小赵 | 2016-12-10 00:04:33 |
| 2 | 小钱 | 2016-12-10 00:04:48 |
| 3 | 小孙 | 2016-12-13 20:25:00 |
| 4 | 小李 | 2016-12-12 00:00:00 |
+----+--------+---------------------+
```

### 限制(对比mysqlbinlog)

* mysql server必须开启,离线模式下不能解析
* 参数 _binlog\_row\_image_ 必须为FULL,暂不支持MINIMAL
* 解析速度不如mysqlbinlog

### 优点(对比mysqlbinlog)

* 纯Python开发,安装与使用都很简单
* 自带flashback、no-primary-key解析模式,无需再装补丁
* flashback模式下,更适合[闪回实战](./example/mysql-flashback-priciple-and-practice.md)
* 解析为标准SQL,方便理解、筛选
* 代码容易改造,可以支持更多个性化解析

 

 

MySQL误操作闪回恢复利器之my2sql (转载于:https://bbs.huaweicloud.com/blogs/344706

【摘要】 一、my2sql简介 二、my2sql用途 三、产品性能对比 四、安装 五、重要参数说明 六、使用案例 6.1 解析出标准SQL 根据时间点解析出标准SQL 根据pos点解析出标准SQL 6.2 解析出回滚SQL 根据时间点解析出回滚SQL 根据pos点解析出回滚SQL 6.3 统计DML以及大事务 统计时间范围各个表的DML操作数量,统计一个事务大于500条、时间大于300秒的事务 统计...
  1. 一、my2sql简介
  2. 二、my2sql用途
  3. 三、产品性能对比
  4. 四、安装
  5. 五、重要参数说明
  6. 六、使用案例
    1. 6.1 解析出标准SQL
      1. 根据时间点解析出标准SQL
      2. 根据pos点解析出标准SQL
    2. 6.2 解析出回滚SQL
      1. 根据时间点解析出回滚SQL
      2. 根据pos点解析出回滚SQL
    3. 6.3 统计DML以及大事务
      1. 统计时间范围各个表的DML操作数量,统计一个事务大于500条、时间大于300秒的事务
      2. 统计一段pos点范围各个表的DML操作数量,统计一个事务大于500条、时间大于300秒的事务
    4. 6.4 从某一个pos点解析出标准SQL,并且持续打印到屏幕
  7. 七、限制
  8. 八、案例演示
    1. 8.1 准备MySQL环境
    2. 8.2 执行DML操作
    3. 8.3 解析binlog生成标准SQL
    4. 8.4 执行闪回操作

一、my2sql简介

可以用于MySQL误操作闪回的工具包括my2sql、binlog2sql和MyFlash等工具,其中,个人感觉my2sql最好用。

my2sql是使用go语言开发的MySQL binlog解析工具,通过解析MySQL binlog ,可以生成原始SQL、回滚SQL、去除主键的INSERT SQL等,也可以生成DML统计信息。类似工具有binlog2sql、MyFlash、my2fback等,本工具基于my2fback、binlog_rollback工具二次开发而来。

my2sql的GitHub地址:https://github.com/liuhr/my2sql

优点:

  • 功能丰富,不仅支持回滚操作,还有其他实用功能。
  • 基于golang实现,速度快,全量解析1.1Gbinlog只需要1分30秒左右,当前其他类似开源工具一般要几十分钟。

二、my2sql用途

  • 数据快速回滚(闪回)
  • 主从切换后新master丢数据的修复
  • 从binlog生成标准SQL,带来的衍生功能
  • 生成DML统计信息,可以找到哪些表更新的比较频繁
  • IO高TPS高, 查出哪些表在频繁更新
  • 找出某个时间点数据库是否有大事务或者长事务
  • 主从延迟,分析主库执行的SQL语句
  • 除了支持常规数据类型,对大部分工具不支持的数据类型做了支持,比如json、blob、text、emoji等数据类型sql生成

三、产品性能对比

binlog2sql当前是业界使用最广泛的MySQL回滚工具,下面对my2sql和binlog2sql做个性能对比。

 my2sqlbinlog2sql
1.1G binlog生成回滚SQL 1分40秒 65分钟
1.1G binlog生成原始SQL 1分30秒 50分钟
1.1G binlog生成表DML统计信息、以及事务统计信息 40秒 不支持

四、安装

-- 申请一台全新的主机
docker rm -f lhrmy2sql
docker run -d --name lhrmy2sql -h lhrmy2sql \
  --privileged=true lhrbest/lhrcentos76:8.0 \
  /usr/sbin/init

docker exec -it lhrmy2sql bash
-- 方法1:编译安装
yum install -y golang
go version
go env | grep GOPATH

mkdir -p /root/go/src
cd /root/go/src
git clone https://github.com/liuhr/my2sql.git
cd my2sql/
go build .
-- 方法2:直接下载编译好的二进制文件。
-- https://github.com/liuhr/my2sql/tree/master/releases
wget https://raw.githubusercontent.com/liuhr/my2sql/master/releases/centOS_release_6.x/my2sql
wget https://raw.githubusercontent.com/liuhr/my2sql/master/releases/centOS_release_7.x/my2sql
mv my2sql /usr/local/bin/my2sql
chmod +x /usr/local/bin/my2sql
-- 若不能下载,请添加以下解析:
echo "
13.229.188.59 github.com
199.232.4.133 raw.githubusercontent.com
" >> /etc/hosts

五、重要参数说明

  • -U 优先使用unique key作为where条件,默认false

  • -add-extraInfo 是否把database/table/datetime/binlogposition…信息以注释的方式加入生成的每条sql前,默认false

datetime=2020-07-16_10:44:09 database=orchestrator table=cluster_domain_name binlog=mysql-bin.011519 startpos=15552 stoppos=15773

UPDATE `orchestrator`.`cluster_domain_name` SET `last_registered`='2020-07-16 10:44:09' WHERE `cluster_name`='192.168.1.1:3306'
  • -big-trx-row-limit n
    transaction with affected rows greater or equal to this value is considerated as big transaction
    找出影响了n行数据的事务,默认500条

  • -databases 、 -tables 库及表条件过滤, 以逗号分隔

  • -sql 要解析的sql类型,可选参数insert、update、delete,默认全部解析

  • -doNotAddPrifixDb
    Prefix table name witch database name in sql,ex: insert into db1.tb1 (x1, x1) values (y1, y1)
    默认生成insert into db1.tb1 (x1, x1) values (y1, y1)类sql,也可以生成不带库名的sql

  • -file-per-table 为每个表生成一个sql文件

  • -full-columns
    For update sql, include unchanged columns. for update and delete, use all columns to build where condition.
    default false, this is, use changed columns to build set part, use primary/unique key to build where condition
    生成的sql是否带全列信息,默认false

  • -ignorePrimaryKeyForInsert 生成的insert语句是否去掉主键,默认false

  • -output-dir 将生成的结果存放到制定目录

  • -output-toScreen 将生成的结果打印到屏幕,默认写到文件

  • -threads 线程数,默认8个

  • -work-type 2sql表示生成原始sql,rollback表示生成回滚sql,stats表示只统计DML、事务信息

六、使用案例

6.1 解析出标准SQL

根据时间点解析出标准SQL

./my2sql  -user root -password xxxx -host 127.0.0.1   -port 3306  -work-type 2sql  \
-start-file mysql-bin.011259  -start-datetime "2020-07-16 10:20:00" -stop-datetime "2020-07-16 11:00:00" \
-output-dir ./tmpdir

根据pos点解析出标准SQL

./my2sql  -user root -password xxxx -host 127.0.0.1   -port 3306  -work-type 2sql  \
-start-file mysql-bin.011259  -start-pos 4 -stop-file mysql-bin.011259 -stop-pos 583918266  \
-output-dir ./tmpdir

6.2 解析出回滚SQL

根据时间点解析出回滚SQL

./my2sql  -user root -password xxxx -host 127.0.0.1   -port 3306  -work-type rollback  \
-start-file mysql-bin.011259  -start-datetime "2020-07-16 10:20:00" -stop-datetime "2020-07-16 11:00:00" \
-output-dir ./tmpdir

根据pos点解析出回滚SQL

./my2sql  -user root -password xxxx -host 127.0.0.1   -port 3306  -work-type rollback  \
-start-file mysql-bin.011259  -start-pos 4 -stop-file mysql-bin.011259 -stop-pos 583918266  \
-output-dir ./tmpdir

6.3 统计DML以及大事务

统计时间范围各个表的DML操作数量,统计一个事务大于500条、时间大于300秒的事务

./my2sql  -user root -password xxxx -host 127.0.0.1   -port 3306  -work-type stats  \
-start-file mysql-bin.011259  -start-datetime "2020-07-16 10:20:00" -stop-datetime "2020-07-16 11:00:00"  \
-big-trx-row-limit 500 -long-trx-seconds 300   -output-dir ./tmpdir

统计一段pos点范围各个表的DML操作数量,统计一个事务大于500条、时间大于300秒的事务

./my2sql  -user root -password xxxx -host 127.0.0.1   -port 3306  -work-type stats  \
-start-file mysql-bin.011259  -start-pos 4 -stop-file mysql-bin.011259 -stop-pos 583918266  \
-big-trx-row-limit 500 -long-trx-seconds 300   -output-dir ./tmpdir

6.4 从某一个pos点解析出标准SQL,并且持续打印到屏幕

./my2sql  -user root -password xxxx -host 127.0.0.1   -port 3306  -work-type 2sql  \
-start-file mysql-bin.011259  -start-pos 4   -output-toScreen 

七、限制

  • 使用回滚/闪回功能时,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权限
  • MySQL8.0版本需要在配置文件中加入default_authentication_plugin=mysql_native_password,用户密码认证必须是mysql_native_password才能解析

八、案例演示

8.1 准备MySQL环境

docker rm -f mysql3306
docker run -d --name mysql3306 -h mysql3306 -p 3306:3306 \
  -v /etc/mysql/mysql3306/conf:/etc/mysql/conf.d \
  -e MYSQL_ROOT_PASSWORD=lhr -e TZ=Asia/Shanghai \
  mysql:5.7.30
docker exec -it mysql3306 bash
docker logs -f mysql3306
cat >  /etc/mysql/mysql3306/conf/my.cnf <<"EOF"
[mysqld]
default-time-zone = '+8:00'
log_timestamps = SYSTEM
skip-name-resolve
log-bin
server_id=573306
character_set_server=utf8mb4
EOF

docker restart mysql3306
mysql -uroot -plhr -h192.168.66.35 -P3306
create database lhrdb default character set utf8mb4;

8.2 执行DML操作

show master logs;
flush logs;
select now();

use lhrdb;
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 DEFAULT CHARSET=utf8;
INSERT INTO `lhrdb`.`student` (`id`,`number`,`name`,`add_time`,`content`) VALUES (1233,26,'ranran','2020-07-15 19:06:03',null);
INSERT INTO `lhrdb`.`student` (`id`,`number`,`name`,`add_time`,`content`) VALUES (1232,134,'asdf','2020-07-12 11:08:41',null);
INSERT INTO `lhrdb`.`student` (`id`,`number`,`name`,`add_time`,`content`) VALUES (1231,21,'chenxi','2020-07-12 10:12:45',null);
INSERT INTO `lhrdb`.`student` (`id`,`number`,`name`,`add_time`,`content`) VALUES (1229,20,'chenxi','2020-07-11 16:20:50',null);
INSERT INTO `lhrdb`.`student` (`id`,`number`,`name`,`add_time`,`content`) VALUES (1227,18,'hanran','2020-07-06 21:55:48','{\"age\":13,\"author\":\"liuhan\"}');

select * from student;
select now();

show master logs;
show binlog events in 'mysql3306-bin.000002';

执行过程:

MySQL [(none)]> show master logs;
+----------------------+-----------+
| Log_name             | File_size |
+----------------------+-----------+
| mysql3306-bin.000001 |   3071539 |
| mysql3306-bin.000002 |       154 |
| mysql3306-bin.000003 |       154 |
+----------------------+-----------+
3 rows in set (0.05 sec)

MySQL [(none)]>
MySQL [(none)]> create database lhrdb default character set utf8mb4;
Query OK, 1 row affected (0.05 sec)

MySQL [(none)]> show master logs;
+----------------------+-----------+
| Log_name             | File_size |
+----------------------+-----------+
| mysql3306-bin.000001 |   3071539 |
| mysql3306-bin.000002 |       154 |
| mysql3306-bin.000003 |       346 |
+----------------------+-----------+
3 rows in set (0.05 sec)

MySQL [(none)]> flush logs;
Query OK, 0 rows affected (0.06 sec)

MySQL [(none)]>
MySQL [(none)]> select now();
+---------------------+
| now()               |
+---------------------+
| 2021-02-26 12:22:38 |
+---------------------+
1 row in set (0.05 sec)

MySQL [(none)]>
MySQL [(none)]> use lhrdb;
Database changed
MySQL [lhrdb]> 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 DEFAULT CHARSET=utf8;
Query OK, 0 rows affected (0.07 sec)

MySQL [lhrdb]> INSERT INTO `lhrdb`.`student` (`id`,`number`,`name`,`add_time`,`content`) VALUES (1233,26,'ranran','2020-07-15 19:06:03',null);
Query OK, 1 row affected (0.08 sec)

MySQL [lhrdb]> INSERT INTO `lhrdb`.`student` (`id`,`number`,`name`,`add_time`,`content`) VALUES (1232,134,'asdf','2020-07-12 11:08:41',null);
Query OK, 1 row affected (0.05 sec)

MySQL [lhrdb]> INSERT INTO `lhrdb`.`student` (`id`,`number`,`name`,`add_time`,`content`) VALUES (1231,21,'chenxi','2020-07-12 10:12:45',null);
Query OK, 1 row affected (0.06 sec)

MySQL [lhrdb]> INSERT INTO `lhrdb`.`student` (`id`,`number`,`name`,`add_time`,`content`) VALUES (1229,20,'chenxi','2020-07-11 16:20:50',null);
Query OK, 1 row affected (0.05 sec)

MySQL [lhrdb]> INSERT INTO `lhrdb`.`student` (`id`,`number`,`name`,`add_time`,`content`) VALUES (1227,18,'hanran','2020-07-06 21:55:48','{\"age\":13,\"author\":\"liuhan\"}');
Query OK, 1 row affected (0.05 sec)

MySQL [lhrdb]>
MySQL [lhrdb]> select * from student;
+------+--------+--------+---------------------+---------------------------------+
| id   | number | name   | add_time            | content                         |
+------+--------+--------+---------------------+---------------------------------+
| 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                            |
+------+--------+--------+---------------------+---------------------------------+
5 rows in set (0.05 sec)

MySQL [lhrdb]> select now();
+---------------------+
| now()               |
+---------------------+
| 2021-02-26 12:23:16 |
+---------------------+
1 row in set (0.05 sec)

MySQL [lhrdb]>
MySQL [lhrdb]> show master logs;
+----------------------+-----------+
| Log_name             | File_size |
+----------------------+-----------+
| mysql3306-bin.000001 |   3071539 |
| mysql3306-bin.000002 |       154 |
| mysql3306-bin.000003 |       397 |
| mysql3306-bin.000004 |      2131 |
+----------------------+-----------+
4 rows in set (0.05 sec)

MySQL [lhrdb]> show binlog events in 'mysql3306-bin.000004';
+----------------------+------+----------------+-----------+-------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Log_name             | Pos  | Event_type     | Server_id | End_log_pos | Info                                                                                                                                                                                                                                                                                                                                                           |
+----------------------+------+----------------+-----------+-------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| mysql3306-bin.000004 |    4 | Format_desc    |    573306 |         123 | Server ver: 5.7.30-log, Binlog ver: 4                                                                                                                                                                                                                                                                                                                          |
| mysql3306-bin.000004 |  123 | Previous_gtids |    573306 |         154 |                                                                                                                                                                                                                                                                                                                                                                |
| mysql3306-bin.000004 |  154 | Anonymous_Gtid |    573306 |         219 | SET @@SESSION.GTID_NEXT= 'ANONYMOUS'                                                                                                                                                                                                                                                                                                                           |
| mysql3306-bin.000004 |  219 | Query          |    573306 |         634 | use `lhrdb`; 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 DEFAULT CHARSET=utf8 |
| mysql3306-bin.000004 |  634 | Anonymous_Gtid |    573306 |         699 | SET @@SESSION.GTID_NEXT= 'ANONYMOUS'                                                                                                                                                                                                                                                                                                                           |
| mysql3306-bin.000004 |  699 | Query          |    573306 |         780 | BEGIN                                                                                                                                                                                                                                                                                                                                                          |
| mysql3306-bin.000004 |  780 | Table_map      |    573306 |         839 | table_id: 108 (lhrdb.student)                                                                                                                                                                                                                                                                                                                                  |
| mysql3306-bin.000004 |  839 | Write_rows     |    573306 |         895 | table_id: 108 flags: STMT_END_F                                                                                                                                                                                                                                                                                                                                |
| mysql3306-bin.000004 |  895 | Xid            |    573306 |         926 | COMMIT /* xid=13 */                                                                                                                                                                                                                                                                                                                                            |
| mysql3306-bin.000004 |  926 | Anonymous_Gtid |    573306 |         991 | SET @@SESSION.GTID_NEXT= 'ANONYMOUS'                                                                                                                                                                                                                                                                                                                           |
| mysql3306-bin.000004 |  991 | Query          |    573306 |        1072 | BEGIN                                                                                                                                                                                                                                                                                                                                                          |
| mysql3306-bin.000004 | 1072 | Table_map      |    573306 |        1131 | table_id: 108 (lhrdb.student)                                                                                                                                                                                                                                                                                                                                  |
| mysql3306-bin.000004 | 1131 | Write_rows     |    573306 |        1185 | table_id: 108 flags: STMT_END_F                                                                                                                                                                                                                                                                                                                                |
| mysql3306-bin.000004 | 1185 | Xid            |    573306 |        1216 | COMMIT /* xid=14 */                                                                                                                                                                                                                                                                                                                                            |
| mysql3306-bin.000004 | 1216 | Anonymous_Gtid |    573306 |        1281 | SET @@SESSION.GTID_NEXT= 'ANONYMOUS'                                                                                                                                                                                                                                                                                                                           |
| mysql3306-bin.000004 | 1281 | Query          |    573306 |        1362 | BEGIN                                                                                                                                                                                                                                                                                                                                                          |
| mysql3306-bin.000004 | 1362 | Table_map      |    573306 |        1421 | table_id: 108 (lhrdb.student)                                                                                                                                                                                                                                                                                                                                  |
| mysql3306-bin.000004 | 1421 | Write_rows     |    573306 |        1477 | table_id: 108 flags: STMT_END_F                                                                                                                                                                                                                                                                                                                                |
| mysql3306-bin.000004 | 1477 | Xid            |    573306 |        1508 | COMMIT /* xid=15 */                                                                                                                                                                                                                                                                                                                                            |
| mysql3306-bin.000004 | 1508 | Anonymous_Gtid |    573306 |        1573 | SET @@SESSION.GTID_NEXT= 'ANONYMOUS'                                                                                                                                                                                                                                                                                                                           |
| mysql3306-bin.000004 | 1573 | Query          |    573306 |        1654 | BEGIN                                                                                                                                                                                                                                                                                                                                                          |
| mysql3306-bin.000004 | 1654 | Table_map      |    573306 |        1713 | table_id: 108 (lhrdb.student)                                                                                                                                                                                                                                                                                                                                  |
| mysql3306-bin.000004 | 1713 | Write_rows     |    573306 |        1769 | table_id: 108 flags: STMT_END_F                                                                                                                                                                                                                                                                                                                                |
| mysql3306-bin.000004 | 1769 | Xid            |    573306 |        1800 | COMMIT /* xid=16 */                                                                                                                                                                                                                                                                                                                                            |
| mysql3306-bin.000004 | 1800 | Anonymous_Gtid |    573306 |        1865 | SET @@SESSION.GTID_NEXT= 'ANONYMOUS'                                                                                                                                                                                                                                                                                                                           |
| mysql3306-bin.000004 | 1865 | Query          |    573306 |        1946 | BEGIN                                                                                                                                                                                                                                                                                                                                                          |
| mysql3306-bin.000004 | 1946 | Table_map      |    573306 |        2005 | table_id: 108 (lhrdb.student)                                                                                                                                                                                                                                                                                                                                  |
| mysql3306-bin.000004 | 2005 | Write_rows     |    573306 |        2100 | table_id: 108 flags: STMT_END_F                                                                                                                                                                                                                                                                                                                                |
| mysql3306-bin.000004 | 2100 | Xid            |    573306 |        2131 | COMMIT /* xid=17 */                                                                                                                                                                                                                                                                                                                                            |
+----------------------+------+----------------+-----------+-------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
29 rows in set (0.05 sec)

8.3 解析binlog生成标准SQL

可以根据时间点解析出标准SQL:

my2sql  -user root -password lhr  -port 3306 \
-host 192.168.66.35 -databases lhrdb  -tables student \
-work-type 2sql   -start-file mysql3306-bin.000004 \
-start-datetime "2021-02-26 12:22:38" --stop-datetime "2021-02-26 12:23:16" \
-output-dir /my2sql/

也可以根据binlog的pos点解析出标准SQL:

my2sql  -user root -password lhr  -port 3306 \
-host 192.168.66.35 -databases lhrdb  -tables student \
-work-type 2sql   -start-file mysql3306-bin.000004 \
-start-pos 154 -stop-file  mysql3306-bin.000004 -stop-pos  2131 \
-output-dir /my2sql/

执行过程:

[root@lhrmy2sql my2sql]# my2sql  -user root -password lhr  -port 3306 \
> -host 192.168.66.35 -databases lhrdb  -tables student \
> -work-type 2sql   -start-file mysql3306-bin.000004 \
> -start-pos 154 -stop-file  mysql3306-bin.000004 -stop-pos  2131 \
> -output-dir /my2sql/
[2021/02/26 12:27:42] [info] events.go:208 start thread to write redo/rollback sql into file
[2021/02/26 12:27:42] [info] binlogsyncer.go:144 create BinlogSyncer with config {1113306 mysql 192.168.66.35 3306 root   utf8 false false <nil> false Local false 0 0s 0s 0 false false 0}
[2021/02/26 12:27:42] [info] binlogsyncer.go:360 begin to sync binlog from position (mysql3306-bin.000004, 154)
[2021/02/26 12:27:42] [info] events.go:58 start thread 2 to generate redo/rollback sql
[2021/02/26 12:27:42] [info] events.go:58 start thread 1 to generate redo/rollback sql
[2021/02/26 12:27:42] [info] stats_process.go:166 start thread to analyze statistics from binlog
[2021/02/26 12:27:42] [info] repl.go:15 start to get binlog from mysql
[2021/02/26 12:27:42] [info] binlogsyncer.go:777 rotate to (mysql3306-bin.000004, 154)
[2021/02/26 12:27:42] [info] com.go:57 stop to get event. StopFilePos set. currentBinlog (mysql3306-bin.000004, 2131) StopFilePos (mysql3306-bin.000004, 2131)
[2021/02/26 12:27:42] [info] repl.go:17 finish getting binlog from mysql
[2021/02/26 12:27:42] [info] events.go:183 exit thread 1 to generate redo/rollback sql
[2021/02/26 12:27:42] [info] stats_process.go:266 exit thread to analyze statistics from binlog
[2021/02/26 12:27:42] [info] events.go:183 exit thread 2 to generate redo/rollback sql
[2021/02/26 12:27:42] [info] events.go:272 finish writing redo/forward sql into file
[2021/02/26 12:27:42] [info] events.go:275 exit thread to write redo/rollback sql into file
[root@lhrmy2sql my2sql]# ll
total 12
-rw-r--r-- 1 root root 107 Feb 26 12:27 biglong_trx.txt
-rw-r--r-- 1 root root 291 Feb 26 12:27 binlog_status.txt
-rw-r--r-- 1 root root 671 Feb 26 12:27 forward.4.sql
[root@lhrmy2sql my2sql]# more biglong_trx.txt 
binlog            starttime           stoptime            startpos   stoppos    rows     duration   tables
[root@lhrmy2sql my2sql]# more binlog_status.txt 
binlog            starttime           stoptime            startpos   stoppos    inserts  updates  deletes  database        table               
mysql3306-bin.000004 2021-02-26_12:23:06 2021-02-26_12:23:06 780        2100       5        0        0        lhrdb           student             
[root@lhrmy2sql my2sql]# more forward.4.sql 
INSERT INTO `lhrdb`.`student` (`id`,`number`,`name`,`add_time`,`content`) VALUES (1233,26,'ranran','2020-07-15 19:06:03',null);
INSERT INTO `lhrdb`.`student` (`id`,`number`,`name`,`add_time`,`content`) VALUES (1232,134,'asdf','2020-07-12 11:08:41',null);
INSERT INTO `lhrdb`.`student` (`id`,`number`,`name`,`add_time`,`content`) VALUES (1231,21,'chenxi','2020-07-12 10:12:45',null);
INSERT INTO `lhrdb`.`student` (`id`,`number`,`name`,`add_time`,`content`) VALUES (1229,20,'chenxi','2020-07-11 16:20:50',null);
INSERT INTO `lhrdb`.`student` (`id`,`number`,`name`,`add_time`,`content`) VALUES (1227,18,'hanran','2020-07-06 21:55:48','{\"age\":13,\"author\":\"liuhan\"}');

可以看到,原始的SQL插入语句已经被解析出来了。

8.4 执行闪回操作

根据binlog的pos点解析出回滚SQL

my2sql  -user root -password lhr  -port 3306 \
-host 192.168.66.35 -databases lhrdb  -tables student \
-work-type rollback   -start-file mysql3306-bin.000004 \
-start-pos 154 -stop-file  mysql3306-bin.000004 -stop-pos  2131 \
-output-dir /my2sql/
 
 
MyFlash

### 一、简介
MyFlash是由美团点评公司技术工程部开发维护的一个回滚DML操作的工具。该工具通过解析v4版本的binlog,完成回滚操作。相对已有的回滚工具,其增加了更多的过滤选项,让回滚更加容易。
**该工具已经在美团点评内部使用**
### 二、详细说明
1. [安装]

### 1.How to build
该工具推荐用户在下载源码之后,进行动态编译链接安装

#### 动态编译链接

```
gcc -w `pkg-config --cflags --libs glib-2.0` source/binlogParseGlib.c -o binary/flashback
```
然而用户不想每次去重新编译,可以选择使用静态链接,但是该方法需要知道glib库的版本和位置,因此对于每台机器略有不同,请谨慎使用

#### 静态编译链接
为了保证在一台机器上编译后,可以在其它机器上使用,需要满足以下两个条件
a) 将glib做成静态链接
b)在编译的那台机器的glibc版本(查看方法为ldd --version)要小于等于要运行该软件的那台机器glibc版本
因此需要你在一台glibc版本较低的机器上运行如下命令即可。
```
gcc -w -g `pkg-config --cflags glib-2.0` source/binlogParseGlib.c -o binary/flashback /usr/lib64/libglib-2.0.a -lrt
```

2. [使用]

### 1.How to use

```
cd binary
./flashback --help

Usage:
flashback [OPTION...]

Help Options:
-?, --help Show help options

Application Options:
--databaseNames databaseName to apply. if multiple, seperate by comma(,)
--tableNames tableName to apply. if multiple, seperate by comma(,)
--start-position start position
--stop-position stop position
--start-datetime start time (format %Y-%m-%d %H:%M:%S)
--stop-datetime stop time (format %Y-%m-%d %H:%M:%S)
--sqlTypes sql type to filter . support INSERT, UPDATE ,DELETE. if multiple, seperate by comma(,)
--maxSplitSize max file size after split, the uint is M
--binlogFileNames binlog files to process. if multiple, seperate by comma(,)
--outBinlogFileNameBase output binlog file name base
--logLevel log level, available option is debug,warning,error
--include-gtids gtids to process
--exclude-gtids gtids to skip
```

### 2.Parameter explantion
下面的这些参数是可以任意组合的。

- 1.databaseNames

指定需要回滚的数据库名。多个数据库可以用“,”隔开。如果不指定该参数,相当于指定了所有数据库。
- 2.tableNames

指定需要回滚的表名。多个表可以用“,”隔开。如果不指定该参数,相当于指定了所有表。
- 3.start-position

指定回滚开始的位置。如不指定,从文件的开始处回滚。请指定正确的有效的位置,否则无法回滚
- 4.stop-position

指定回滚结束的位置。如不指定,回滚到文件结尾。请指定正确的有效的位置,否则无法回滚
- 5.start-datetime

指定回滚的开始时间。注意格式必须是 %Y-%m-%d %H:%M:%S。 如不指定,则不限定时间
- 6.stop-datetime

指定回滚的结束时间。注意格式必须是 %Y-%m-%d %H:%M:%S。 如不指定,则不限定时间
- 7.sqlTypes

指定需要回滚的sql类型。目前支持的过滤类型是INSERT, UPDATE ,DELETE。多个类型可以用“,”隔开。
- 8.maxSplitSize

*一旦指定该参数,对文件进行固定尺寸的分割(单位为M),过滤条件有效,但不进行回滚操作。该参数主要用来将大的binlog文件切割,防止单次应用的binlog尺寸过大,对线上造成压力*
- 9.binlogFileNames

指定需要回滚的binlog文件,目前只支持单个文件,后续会增加多个文件支持
- 10.outBinlogFileNameBase

指定输出的binlog文件前缀,如不指定,则默认为binlog_output_base.flashback
- 11.logLevel

仅供开发者使用,默认级别为error级别。在生产环境中不要修改这个级别,否则输出过多
- 12.include-gtids

指定需要回滚的gtid,支持gtid的单个和范围两种形式。
- 13.exclude-gtids

指定不需要回滚的gtid,用法同include-gtids


### 3.example

1.回滚整个文件
```
./flashback --binlogFileNames=haha.000041
mysqlbinlog binlog_output_base.flashback | mysql -h<host> -u<user> -p
```
2.回滚该文件中的所有insert语句
```
./flashback --sqlTypes='INSERT' --binlogFileNames=haha.000041
mysqlbinlog binlog_output_base.flashback | mysql -h<host> -u<user> -p
```
3.回滚大文件
```
回滚
./flashback --binlogFileNames=haha.000042
切割大文件
./flashback --maxSplitSize=1 --binlogFileNames=binlog_output_base.flashback
应用
mysqlbinlog binlog_output_base.flashback.000001 | mysql -h<host> -u<user> -p
...
mysqlbinlog binlog_output_base.flashback.<N> | mysql -h<host> -u<user> -p
```


3. [测试用例]

###测试表结构
```
CREATE TABLE `testFlashback2` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`nameShort` varchar(20) DEFAULT NULL,
`nameLong` varchar(260) DEFAULT NULL,
`amount` decimal(19,9) DEFAULT NULL,
`amountFloat` float DEFAULT NULL,
`amountDouble` double DEFAULT NULL,
`createDatetime6` datetime(6) DEFAULT NULL,
`createDatetime` datetime DEFAULT NULL,
`createTimestamp` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`nameText` text,
`nameBlob` blob,
`nameMedium` mediumtext,
PRIMARY KEY (`id`)
) ENGINE=InnoDB
```
####插入回滚
```
flush logs
insert into testFlashback2(nameShort,nameLong,amount,amountFloat,amountDouble,createDatetime6,createDatetime,createTimestamp,nameText,nameBlob,nameMedium) values('aaa','bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb',10.5,10.6,10.7,'2017-10-26 10:00:00','2017-10-26 10:00:00','2017-10-26 10:00:00','cccc','dddd','eee');
insert into testFlashback2(nameShort,nameLong,amount,amountFloat,amountDouble,createDatetime6,createDatetime,createTimestamp,nameText,nameBlob,nameMedium) values('aaa','bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb',10.5,10.6,10.7,'2017-10-26 10:00:00','2017-10-26 10:00:00','2017-10-26 10:00:00','cccc','dddd','eee');
flush logs;
./binary/flashback --binlogFileNames=/var/lib/mysql/haha.000048
在当前运行目录下产生binlog_output_base.flashback文件
mysqlbinlog --skip-gtids binlog_output_base.flashback | mysql --socket=/var/lib/mysql/mysql.sock test
执行结果
mysql> select * from testFlashback2;
Empty set (0.00 sec)
```
插入回滚成功
####删除回滚
```
delete from testFlashback2;
insert into testFlashback2(nameShort,nameLong,amount,amountFloat,amountDouble,createDatetime6,createDatetime,createTimestamp,nameText,nameBlob,nameMedium) values('aaa','bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb',10.5,10.6,10.7,'2017-10-26 10:00:00','2017-10-26 10:00:00','2017-10-26 10:00:00','cccc','dddd','eee');
flush logs;
delete from testFlashback2;
./binary/flashback --binlogFileNames=/var/lib/mysql/haha.000050
在当前运行目录下产生binlog_output_base.flashback文件
mysqlbinlog --skip-gtids binlog_output_base.flashback | mysql --socket=/var/lib/mysql/mysql.sock test
执行结果
+----+-----------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+--------------+-------------+--------------+----------------------------+---------------------+---------------------+----------+----------+------------+
| id | nameShort | nameLong | amount | amountFloat | amountDouble | createDatetime6 | createDatetime | createTimestamp | nameText | nameBlob | nameMedium |
+----+-----------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+--------------+-------------+--------------+----------------------------+---------------------+---------------------+----------+----------+------------+
| 4 | aaa | bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb | 10.500000000 | 10.6 | 10.7 | 2017-10-26 10:00:00.000000 | 2017-10-26 10:00:00 | 2017-10-26 10:00:00 | cccc | dddd | eee |
+----+-----------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+--------------+-------------+--------------+----------------------------+---------------------+---------------------+----------+----------+------------+
```
####更新回滚
```
delete from testFlashback2;
insert into testFlashback2(nameShort,nameLong,amount,amountFloat,amountDouble,createDatetime6,createDatetime,createTimestamp,nameText,nameBlob,nameMedium) values('aaa','bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb',10.111,10.6,10.7,'2017-10-26 10:00:00','2017-10-26 10:00:00','2017-10-26 10:00:00','cccc','dddd','eee');
flush logs;
mysql> checksum table testFlashback2;
+---------------------+-----------+
| Table | Checksum |
+---------------------+-----------+
| test.testFlashback2 | 717087411 |
+---------------------+-----------+
update testFlashback2 set amount=10.222;
mysql> checksum table testFlashback2;
+---------------------+------------+
| Table | Checksum |
+---------------------+------------+
| test.testFlashback2 | 3797190846 |
+---------------------+------------+
./binary/flashback --binlogFileNames=/var/lib/mysql/haha.000052
mysqlbinlog --skip-gtids binlog_output_base.flashback | mysql --socket=/var/lib/mysql/mysql.sock test
mysql> checksum table testFlashback2;
+---------------------+-----------+
| Table | Checksum |
+---------------------+-----------+
| test.testFlashback2 | 717087411 |
+---------------------+-----------+
```

####更新回滚(beta环境业务表,总数据量100w,回滚1k数据)
```
CREATE TABLE `DP_FeedBackForPOI_For_Flashback` (
`FeedID` int(11) NOT NULL AUTO_INCREMENT,
`UserName` varchar(50) DEFAULT NULL,
`UserEmail` varchar(100) DEFAULT NULL,
`UserPhone` varchar(20) DEFAULT NULL,
`UserID` int(11) DEFAULT '0',
`FeedTitle` varchar(200) DEFAULT NULL,
`FeedComments` text,
`FeedAdddate` datetime DEFAULT NULL,
`FeedStatus` tinyint(3) unsigned DEFAULT '0',
`SendTitle` varchar(200) DEFAULT NULL,
`SendComments` text,
`SendDate` datetime DEFAULT NULL,
`MailTO` varchar(100) DEFAULT NULL,
`FeedType` tinyint(3) unsigned DEFAULT '0',
`LastAdminID` smallint(6) DEFAULT NULL,
`ReferID` int(11) DEFAULT '0',
`ReferUserID` int(11) DEFAULT '0',
`ReferShopID` int(11) DEFAULT '0',
`FeedGroupID` int(11) DEFAULT '0',
`CauseType` tinyint(4) DEFAULT '0',
`ClientType` tinyint(4) DEFAULT '0',
`LastAdminName` varchar(50) DEFAULT NULL,
PRIMARY KEY (`FeedID`),
KEY `LastAdminID` (`LastAdminID`) USING BTREE,
KEY `FeedStatus` (`FeedStatus`,`FeedAdddate`,`FeedType`) USING BTREE,
KEY `MailTO` (`MailTO`,`FeedAdddate`,`FeedStatus`) USING BTREE,
KEY `FeedType` (`FeedType`,`FeedAdddate`,`UserEmail`) USING BTREE,
KEY `FeedGroupID` (`FeedGroupID`) USING BTREE,
KEY `FeedID_FeedStatus` (`FeedStatus`,`FeedGroupID`) USING BTREE,
KEY `UserName` (`UserName`,`MailTO`,`FeedType`,`FeedGroupID`) USING BTREE,
KEY `IX_UserID` (`UserID`) USING BTREE,
KEY `IX_ReferUserID` (`ReferUserID`) USING BTREE,
KEY `IX_ReferShopID` (`ReferShopID`) USING BTREE,
KEY `FeedType_2` (`FeedType`,`ReferID`)
) ENGINE=InnoDB AUTO_INCREMENT=2078564 DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT;
mysql> checksum table DP_FeedBackForPOI_For_Flashback;
+---------------------------------+-----------+
| Table | Checksum |
+---------------------------------+-----------+
| DP_FeedBackForPOI_For_Flashback | 717087411 |
+---------------------------------+-----------+
update DP_FeedBackForPOI_For_Flashback set UserName='wangguangyou' limit 1000;
mysql> checksum table DP_FeedBackForPOI_For_Flashback;
+---------------------------------+-----------+
| Table | Checksum |
+---------------------------------+-----------+
| DP_FeedBackForPOI_For_Flashback | 3532811761|
+---------------------------------+-----------+
./binary/flashback --binlogFileNames=/var/lib/mysql/haha.000058
mysqlbinlog --skip-gtids binlog_output_base.flashback | mysql --socket=/var/lib/mysql/mysql.sock test
mysql> checksum table DP_FeedBackForPOI_For_Flashback;
+---------------------------------+-----------+
| Table | Checksum |
+---------------------------------+-----------+
| DP_FeedBackForPOI_For_Flashback | 717087411 |
+---------------------------------+-----------+
```


### 三、限制
1. binlog格式必须为row,且binlog_row_image=full
2. 仅支持5.6与5.7
3. 只能回滚DML(增、删、改)
### 四、FAQ
1. 实现的原理是什么?
- 答:参考文章http://url.cn/5yVTfLY

2. 支持gtid吗?
- 答:支持。请参考 [使用](./doc/how_to_use.md)

3. 在开启gtid的MySQL server上,应用flashback报错,错误为:ERROR 1782 (HY000) at line 16: @@SESSION.GTID_NEXT cannot be set to ANONYMOUS when @@GLOBAL.GTID_MODE = ON. ?
- 答:在导入时加入--skip-gtids
mysqlbinlog --skip-gtids <flashbacklog> | mysql -uxxx -pxxx

4. 如果回滚后的binlog日志尺寸超过20M,在导入时,很耗时。如何处理?
- 答:参考 [使用](./doc/how_to_use.md) ,搜索maxSplitSize。使用该参数可以对文件进行切片

posted @ 2022-08-09 22:19  Harda  阅读(512)  评论(0编辑  收藏  举报