作者:网易数据库团队

上篇介绍了DDL闪回,本篇继续介绍DML闪回,相信大家已经比较熟悉。为了使用起来更加方便,我们结合RDS使用需求进一步更加了一些参数。

DML fashback原理

目前DML flashback功能集成于官方mysqlbinlog命令,通过参数的方式进行flashback功能的开启。

官方mysqlbinlog命令为解析MySQL的二进制日志。当二进制日志的格式为ROW格式时,可以输出每个操作的每条记录的前项与后项。那么通过逆操作即可进行回滚操作,例如:原始操作:INSERT INTO ... Flashback操作:DELETE ...

原始操作:DELETE FROM ...Flashback操作:INSERT INTO ...

原始操作:UPDATE XXX SET OLD_VALUES ...Flashback操作:UPDATE XXX SET NEW_VALUES ...

DML的flashback相关参数说明

目前支持的参数如下:

-B,--flashback

解析Binlog生成flashback语句进行回滚。

例1: 闪回update操作。

create table t1(a int);
insert into t1 values(1);
flush logs;
update t1 set a = 2;
mysql> show binlog events in "mysql-bin.000003";

找出event起止位置191,459。

mysqlbinlog -B --start-position=191 --stop-position=459 mysql-bin.000003 > fb.sql

-A,--skip-database

解析BinLog时过滤掉该数据库。见例2。

-a,--skip-table

解析BinLog时过滤掉该表,一般与skip-datebase配套使用。

例2:--skip-database和--skip-table进行库和表的过滤。

create database test1;
create database test2;
create table test1.t1(a int);
create table test2.t2(a int);
create table test2.t3(b int);
flush logs;
insert into test1.t1 values(1);
insert into test2.t2 value (2);
insert into test2.t3 value (3);
mysql> show binlog events in "mysql-bin.000003";

找出event起止位置191,935。

mysqlbinlog -B --skip-database=test2 --skip-table=t2 --start-position=191 --stop-position=935 mysql-bin.000003 > fb.sql

test2.t2表被过滤掉了,没有被回滚。

-O,--split-size-interval

将BinLog文件按照指定的大小拆分为多个段,解析结果为打印每个段的起始offset位置。

注意,当进行flashback时,flashback的内容先保存在内存中。若你的binlog大小为10G,那么需要额外的10G内存先暂时保存这部分信息。在某些情况下,如云环境、或服务器内存较小,会导致无法输出flashback的日志。这时可以通过此参数来设置内存保存文件的大小,例如将此值设置为100M,那么会将Binlog文件按照100M切分为多个段,然后分段进行回滚。

例3:按照指定split-size-interval大小512B和1024B分别切分如下Binlog。

mysqlbinlog --split-size-interval=512 mysql-bin.000016 | grep @start
mysqlbinlog --split-size-interval=1024 mysql-bin.000016 | grep @start
-C,--datetime-to-pos

基于输入的时间信息,解析出该时间对应的第一个BinLog event偏移位置,格式参照start-datetime,flashback时要先找到起始的偏移量,DBA可以先通过此参数定位到具体位置,然后再进行flashback操作。

例4:如下Binlog,解析2019-02-21 14:03:45时间对应的位置。

mysqlbinlog --datetime-to-pos=”2019-02-21 14:03:45” mysql-bin.000016 | grep @datetime_to_pos

-T,--table

仅解析该表,一般与database配套使用。见例5。

-E,--fb-event

仅解析该类型的Log event,一般与database、table选项配套使用。可选的值有:DELETE

INSERT

UPDATE

例5:--database、--table和--fb-event回滚delete。

create database test;
use test;
create table t1(a int);
flush logs;
insert into t1 values(1);
update t1 set a = 2;
insert into t1 values(3);
delete from t1 where a = 3;
mysql> show binlog events in "mysql-bin.000003"

;

找出event起止位置191,1218。

mysqlbinlog -B --database=test --table=t1 --fb-event delete --start-position=191 --stop-position=1218 mysql-bin.000003 > fb.sql