summaryrefslogtreecommitdiff
path: root/mysql-test/suite/binlog
diff options
context:
space:
mode:
authorMonty <monty@mariadb.org>2017-01-20 15:33:28 +0200
committerMonty <monty@mariadb.org>2017-01-20 15:33:28 +0200
commitd75d8631ed2d6af730931ea7079ec7e512e61796 (patch)
tree3b19d3e604354e3cba6b61468b00e9367cfc955a /mysql-test/suite/binlog
parentb9631b46337b2ad76f0cc336cb2990e6bb8ad6f6 (diff)
downloadmariadb-git-d75d8631ed2d6af730931ea7079ec7e512e61796.tar.gz
[MDEV-10570] Add Flashback support
==== Description ==== Flashback can rollback the instances/databases/tables to an old snapshot. It's implement on Server-Level by full image format binary logs (--binlog-row-image=FULL), so it supports all engines. Currently, it’s a feature inside mysqlbinlog tool (with --flashback arguments). Because the flashback binlog events will store in the memory, you should check if there is enough memory in your machine. ==== New Arguments to mysqlbinlog ==== --flashback (-B) It will let mysqlbinlog to work on FLASHBACK mode. ==== New Arguments to mysqld ==== --flashback Setup the server to use flashback. This enables binary log in row mode and will enable extra logging for DDL's needed by flashback feature ==== Example ==== I have a table "t" in database "test", we can compare the output with "--flashback" and without. #client/mysqlbinlog /data/mysqldata_10.0/binlog/mysql-bin.000001 -vv -d test -T t --start-datetime="2013-03-27 14:54:00" > /tmp/1.sql #client/mysqlbinlog /data/mysqldata_10.0/binlog/mysql-bin.000001 -vv -d test -T t --start-datetime="2013-03-27 14:54:00" -B > /tmp/2.sql Then, importing the output flashback file (/tmp/2.log), it can flashback your database/table to the special time (--start-datetime). And if you know the exact postion, "--start-postion" is also works, mysqlbinlog will output the flashback logs that can flashback to "--start-postion" position. ==== Implement ==== 1. As we know, if binlog_format is ROW (binlog-row-image=FULL in 10.1 and later), all columns value are store in the row event, so we can get the data before mis-operation. 2. Just do following things: 2.1 Change Event Type, INSERT->DELETE, DELETE->INSERT. For example: INSERT INTO t VALUES (...) ---> DELETE FROM t WHERE ... DELETE FROM t ... ---> INSERT INTO t VALUES (...) 2.2 For Update_Event, swapping the SET part and WHERE part. For example: UPDATE t SET cols1 = vals1 WHERE cols2 = vals2 ---> UPDATE t SET cols2 = vals2 WHERE cols1 = vals1 2.3 For Multi-Rows Event, reverse the rows sequence, from the last row to the first row. For example: DELETE FROM t WHERE id=1; DELETE FROM t WHERE id=2; ...; DELETE FROM t WHERE id=n; ---> DELETE FROM t WHERE id=n; ...; DELETE FROM t WHERE id=2; DELETE FROM t WHERE id=1; 2.4 Output those events from the last one to the first one which mis-operation happened. For example:
Diffstat (limited to 'mysql-test/suite/binlog')
-rw-r--r--mysql-test/suite/binlog/r/flashback.result480
-rw-r--r--mysql-test/suite/binlog/t/flashback-master.opt2
-rw-r--r--mysql-test/suite/binlog/t/flashback.test163
3 files changed, 645 insertions, 0 deletions
diff --git a/mysql-test/suite/binlog/r/flashback.result b/mysql-test/suite/binlog/r/flashback.result
new file mode 100644
index 00000000000..94833c5224a
--- /dev/null
+++ b/mysql-test/suite/binlog/r/flashback.result
@@ -0,0 +1,480 @@
+#
+# Preparatory cleanup.
+#
+DROP TABLE IF EXISTS t1;
+#
+# We need a fixed timestamp to avoid varying results.
+#
+SET timestamp=1000000000;
+#
+# Delete all existing binary logs.
+#
+RESET MASTER;
+CREATE TABLE t1 (
+c01 tinyint,
+c02 smallint,
+c03 mediumint,
+c04 int,
+c05 bigint,
+c06 char(10),
+c07 varchar(20),
+c08 TEXT
+) ENGINE=InnoDB;
+#
+# Insert data to t1
+#
+INSERT INTO t1 VALUES(0,0,0,0,0,'','','');
+INSERT INTO t1 VALUES(1,2,3,4,5, "abc", "abcdefg", "abcedfghijklmnopqrstuvwxyz");
+INSERT INTO t1 VALUES(127, 32767, 8388607, 2147483647, 9223372036854775807, repeat('a', 10), repeat('a', 20), repeat('a', 255));
+#
+# Update t1
+#
+UPDATE t1 SET c01=100 WHERE c02=0 OR c03=3;
+#
+# Clear t1
+#
+DELETE FROM t1;
+FLUSH LOGS;
+#
+# Show mysqlbinlog result without -B
+#
+/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/;
+/*!40019 SET @@session.max_insert_delayed_threads=0*/;
+/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
+DELIMITER /*!*/;
+# at #
+#010909 9:46:40 server id 1 end_log_pos # CRC32 XXX Start: binlog v 4, server v #.##.## created 010909 9:46:40 at startup
+ROLLBACK/*!*/;
+# at #
+#010909 9:46:40 server id 1 end_log_pos # CRC32 XXX Gtid list []
+# at #
+#010909 9:46:40 server id 1 end_log_pos # CRC32 XXX Binlog checkpoint master-bin.000001
+# at #
+#010909 9:46:40 server id 1 end_log_pos # CRC32 XXX GTID 0-1-1 ddl
+/*!100101 SET @@session.skip_parallel_replication=0*//*!*/;
+/*!100001 SET @@session.gtid_domain_id=0*//*!*/;
+/*!100001 SET @@session.server_id=1*//*!*/;
+/*!100001 SET @@session.gtid_seq_no=1*//*!*/;
+# at #
+#010909 9:46:40 server id 1 end_log_pos # CRC32 XXX Query thread_id=# exec_time=# error_code=0
+use `test`/*!*/;
+SET TIMESTAMP=1000000000/*!*/;
+SET @@session.pseudo_thread_id=#/*!*/;
+SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=0, @@session.unique_checks=1, @@session.autocommit=1, @@session.check_constraint_checks=1/*!*/;
+SET @@session.sql_mode=1342177280/*!*/;
+SET @@session.auto_increment_increment=1, @@session.auto_increment_offset=1/*!*/;
+/*!\C latin1 *//*!*/;
+SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8/*!*/;
+SET @@session.lc_time_names=0/*!*/;
+SET @@session.collation_database=DEFAULT/*!*/;
+CREATE TABLE t1 (
+c01 tinyint,
+c02 smallint,
+c03 mediumint,
+c04 int,
+c05 bigint,
+c06 char(10),
+c07 varchar(20),
+c08 TEXT
+) ENGINE=InnoDB
+/*!*/;
+# at #
+#010909 9:46:40 server id 1 end_log_pos # CRC32 XXX GTID 0-1-2 trans
+/*!100001 SET @@session.gtid_seq_no=2*//*!*/;
+BEGIN
+/*!*/;
+# at #
+#010909 9:46:40 server id 1 end_log_pos # CRC32 XXX Table_map: `test`.`t1` mapped to number #
+# at #
+#010909 9:46:40 server id 1 end_log_pos # CRC32 XXX Write_rows: table id # flags: STMT_END_F
+### INSERT INTO `test`.`t1`
+### SET
+### @1=0 /* TINYINT meta=0 nullable=1 is_null=0 */
+### @2=0 /* SHORTINT meta=0 nullable=1 is_null=0 */
+### @3=0 /* MEDIUMINT meta=0 nullable=1 is_null=0 */
+### @4=0 /* INT meta=0 nullable=1 is_null=0 */
+### @5=0 /* LONGINT meta=0 nullable=1 is_null=0 */
+### @6='' /* STRING(10) meta=65034 nullable=1 is_null=0 */
+### @7='' /* VARSTRING(20) meta=20 nullable=1 is_null=0 */
+### @8='' /* BLOB/TEXT meta=2 nullable=1 is_null=0 */
+# at #
+#010909 9:46:40 server id 1 end_log_pos # CRC32 XXX Xid = #
+COMMIT/*!*/;
+# at #
+#010909 9:46:40 server id 1 end_log_pos # CRC32 XXX GTID 0-1-3 trans
+/*!100001 SET @@session.gtid_seq_no=3*//*!*/;
+BEGIN
+/*!*/;
+# at #
+#010909 9:46:40 server id 1 end_log_pos # CRC32 XXX Table_map: `test`.`t1` mapped to number #
+# at #
+#010909 9:46:40 server id 1 end_log_pos # CRC32 XXX Write_rows: table id # flags: STMT_END_F
+### INSERT INTO `test`.`t1`
+### SET
+### @1=1 /* TINYINT meta=0 nullable=1 is_null=0 */
+### @2=2 /* SHORTINT meta=0 nullable=1 is_null=0 */
+### @3=3 /* MEDIUMINT meta=0 nullable=1 is_null=0 */
+### @4=4 /* INT meta=0 nullable=1 is_null=0 */
+### @5=5 /* LONGINT meta=0 nullable=1 is_null=0 */
+### @6='abc' /* STRING(10) meta=65034 nullable=1 is_null=0 */
+### @7='abcdefg' /* VARSTRING(20) meta=20 nullable=1 is_null=0 */
+### @8='abcedfghijklmnopqrstuvwxyz' /* BLOB/TEXT meta=2 nullable=1 is_null=0 */
+# at #
+#010909 9:46:40 server id 1 end_log_pos # CRC32 XXX Xid = #
+COMMIT/*!*/;
+# at #
+#010909 9:46:40 server id 1 end_log_pos # CRC32 XXX GTID 0-1-4 trans
+/*!100001 SET @@session.gtid_seq_no=4*//*!*/;
+BEGIN
+/*!*/;
+# at #
+#010909 9:46:40 server id 1 end_log_pos # CRC32 XXX Table_map: `test`.`t1` mapped to number #
+# at #
+#010909 9:46:40 server id 1 end_log_pos # CRC32 XXX Write_rows: table id # flags: STMT_END_F
+### INSERT INTO `test`.`t1`
+### SET
+### @1=127 /* TINYINT meta=0 nullable=1 is_null=0 */
+### @2=32767 /* SHORTINT meta=0 nullable=1 is_null=0 */
+### @3=8388607 /* MEDIUMINT meta=0 nullable=1 is_null=0 */
+### @4=2147483647 /* INT meta=0 nullable=1 is_null=0 */
+### @5=9223372036854775807 /* LONGINT meta=0 nullable=1 is_null=0 */
+### @6='aaaaaaaaaa' /* STRING(10) meta=65034 nullable=1 is_null=0 */
+### @7='aaaaaaaaaaaaaaaaaaaa' /* VARSTRING(20) meta=20 nullable=1 is_null=0 */
+### @8='aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' /* BLOB/TEXT meta=2 nullable=1 is_null=0 */
+# at #
+#010909 9:46:40 server id 1 end_log_pos # CRC32 XXX Xid = #
+COMMIT/*!*/;
+# at #
+#010909 9:46:40 server id 1 end_log_pos # CRC32 XXX GTID 0-1-5 trans
+/*!100001 SET @@session.gtid_seq_no=5*//*!*/;
+BEGIN
+/*!*/;
+# at #
+#010909 9:46:40 server id 1 end_log_pos # CRC32 XXX Table_map: `test`.`t1` mapped to number #
+# at #
+#010909 9:46:40 server id 1 end_log_pos # CRC32 XXX Update_rows: table id # flags: STMT_END_F
+### UPDATE `test`.`t1`
+### WHERE
+### @1=0 /* TINYINT meta=0 nullable=1 is_null=0 */
+### @2=0 /* SHORTINT meta=0 nullable=1 is_null=0 */
+### @3=0 /* MEDIUMINT meta=0 nullable=1 is_null=0 */
+### @4=0 /* INT meta=0 nullable=1 is_null=0 */
+### @5=0 /* LONGINT meta=0 nullable=1 is_null=0 */
+### @6='' /* STRING(10) meta=65034 nullable=1 is_null=0 */
+### @7='' /* VARSTRING(20) meta=20 nullable=1 is_null=0 */
+### @8='' /* BLOB/TEXT meta=2 nullable=1 is_null=0 */
+### SET
+### @1=100 /* TINYINT meta=0 nullable=1 is_null=0 */
+### @2=0 /* SHORTINT meta=0 nullable=1 is_null=0 */
+### @3=0 /* MEDIUMINT meta=0 nullable=1 is_null=0 */
+### @4=0 /* INT meta=0 nullable=1 is_null=0 */
+### @5=0 /* LONGINT meta=0 nullable=1 is_null=0 */
+### @6='' /* STRING(10) meta=65034 nullable=1 is_null=0 */
+### @7='' /* VARSTRING(20) meta=20 nullable=1 is_null=0 */
+### @8='' /* BLOB/TEXT meta=2 nullable=1 is_null=0 */
+### UPDATE `test`.`t1`
+### WHERE
+### @1=1 /* TINYINT meta=0 nullable=1 is_null=0 */
+### @2=2 /* SHORTINT meta=0 nullable=1 is_null=0 */
+### @3=3 /* MEDIUMINT meta=0 nullable=1 is_null=0 */
+### @4=4 /* INT meta=0 nullable=1 is_null=0 */
+### @5=5 /* LONGINT meta=0 nullable=1 is_null=0 */
+### @6='abc' /* STRING(10) meta=65034 nullable=1 is_null=0 */
+### @7='abcdefg' /* VARSTRING(20) meta=20 nullable=1 is_null=0 */
+### @8='abcedfghijklmnopqrstuvwxyz' /* BLOB/TEXT meta=2 nullable=1 is_null=0 */
+### SET
+### @1=100 /* TINYINT meta=0 nullable=1 is_null=0 */
+### @2=2 /* SHORTINT meta=0 nullable=1 is_null=0 */
+### @3=3 /* MEDIUMINT meta=0 nullable=1 is_null=0 */
+### @4=4 /* INT meta=0 nullable=1 is_null=0 */
+### @5=5 /* LONGINT meta=0 nullable=1 is_null=0 */
+### @6='abc' /* STRING(10) meta=65034 nullable=1 is_null=0 */
+### @7='abcdefg' /* VARSTRING(20) meta=20 nullable=1 is_null=0 */
+### @8='abcedfghijklmnopqrstuvwxyz' /* BLOB/TEXT meta=2 nullable=1 is_null=0 */
+# at #
+#010909 9:46:40 server id 1 end_log_pos # CRC32 XXX Xid = #
+COMMIT/*!*/;
+# at #
+#010909 9:46:40 server id 1 end_log_pos # CRC32 XXX GTID 0-1-6 trans
+/*!100001 SET @@session.gtid_seq_no=6*//*!*/;
+BEGIN
+/*!*/;
+# at #
+#010909 9:46:40 server id 1 end_log_pos # CRC32 XXX Table_map: `test`.`t1` mapped to number #
+# at #
+#010909 9:46:40 server id 1 end_log_pos # CRC32 XXX Delete_rows: table id # flags: STMT_END_F
+### DELETE FROM `test`.`t1`
+### WHERE
+### @1=100 /* TINYINT meta=0 nullable=1 is_null=0 */
+### @2=0 /* SHORTINT meta=0 nullable=1 is_null=0 */
+### @3=0 /* MEDIUMINT meta=0 nullable=1 is_null=0 */
+### @4=0 /* INT meta=0 nullable=1 is_null=0 */
+### @5=0 /* LONGINT meta=0 nullable=1 is_null=0 */
+### @6='' /* STRING(10) meta=65034 nullable=1 is_null=0 */
+### @7='' /* VARSTRING(20) meta=20 nullable=1 is_null=0 */
+### @8='' /* BLOB/TEXT meta=2 nullable=1 is_null=0 */
+### DELETE FROM `test`.`t1`
+### WHERE
+### @1=100 /* TINYINT meta=0 nullable=1 is_null=0 */
+### @2=2 /* SHORTINT meta=0 nullable=1 is_null=0 */
+### @3=3 /* MEDIUMINT meta=0 nullable=1 is_null=0 */
+### @4=4 /* INT meta=0 nullable=1 is_null=0 */
+### @5=5 /* LONGINT meta=0 nullable=1 is_null=0 */
+### @6='abc' /* STRING(10) meta=65034 nullable=1 is_null=0 */
+### @7='abcdefg' /* VARSTRING(20) meta=20 nullable=1 is_null=0 */
+### @8='abcedfghijklmnopqrstuvwxyz' /* BLOB/TEXT meta=2 nullable=1 is_null=0 */
+### DELETE FROM `test`.`t1`
+### WHERE
+### @1=127 /* TINYINT meta=0 nullable=1 is_null=0 */
+### @2=32767 /* SHORTINT meta=0 nullable=1 is_null=0 */
+### @3=8388607 /* MEDIUMINT meta=0 nullable=1 is_null=0 */
+### @4=2147483647 /* INT meta=0 nullable=1 is_null=0 */
+### @5=9223372036854775807 /* LONGINT meta=0 nullable=1 is_null=0 */
+### @6='aaaaaaaaaa' /* STRING(10) meta=65034 nullable=1 is_null=0 */
+### @7='aaaaaaaaaaaaaaaaaaaa' /* VARSTRING(20) meta=20 nullable=1 is_null=0 */
+### @8='aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' /* BLOB/TEXT meta=2 nullable=1 is_null=0 */
+# at #
+#010909 9:46:40 server id 1 end_log_pos # CRC32 XXX Xid = #
+COMMIT/*!*/;
+# at #
+#010909 9:46:40 server id 1 end_log_pos # CRC32 XXX Rotate to master-bin.000002 pos: 4
+DELIMITER ;
+# End of log file
+ROLLBACK /* added by mysqlbinlog */;
+/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
+/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;
+#
+# Show mysqlbinlog result with -B
+#
+/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/;
+/*!40019 SET @@session.max_insert_delayed_threads=0*/;
+/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
+DELIMITER /*!*/;
+#010909 9:46:40 server id 1 end_log_pos # CRC32 XXX Start: binlog v 4, server v #.##.## created 010909 9:46:40 at startup
+ROLLBACK/*!*/;
+#010909 9:46:40 server id 1 end_log_pos # CRC32 XXX Gtid list []
+#010909 9:46:40 server id 1 end_log_pos # CRC32 XXX Binlog checkpoint master-bin.000001
+#010909 9:46:40 server id 1 end_log_pos # CRC32 XXX Table_map: `test`.`t1` mapped to number #
+#010909 9:46:40 server id 1 end_log_pos # CRC32 XXX Table_map: `test`.`t1` mapped to number #
+#010909 9:46:40 server id 1 end_log_pos # CRC32 XXX Table_map: `test`.`t1` mapped to number #
+#010909 9:46:40 server id 1 end_log_pos # CRC32 XXX Table_map: `test`.`t1` mapped to number #
+#010909 9:46:40 server id 1 end_log_pos # CRC32 XXX Table_map: `test`.`t1` mapped to number #
+#010909 9:46:40 server id 1 end_log_pos # CRC32 XXX Rotate to master-bin.000002 pos: 4
+#010909 9:46:40 server id 1 end_log_pos # CRC32 XXX Xid = #
+BEGIN/*!*/;
+#010909 9:46:40 server id 1 end_log_pos # CRC32 XXX Write_rows: table id # flags: STMT_END_F
+### INSERT INTO `test`.`t1`
+### SET
+### @1=127 /* TINYINT meta=0 nullable=1 is_null=0 */
+### @2=32767 /* SHORTINT meta=0 nullable=1 is_null=0 */
+### @3=8388607 /* MEDIUMINT meta=0 nullable=1 is_null=0 */
+### @4=2147483647 /* INT meta=0 nullable=1 is_null=0 */
+### @5=9223372036854775807 /* LONGINT meta=0 nullable=1 is_null=0 */
+### @6='aaaaaaaaaa' /* STRING(10) meta=65034 nullable=1 is_null=0 */
+### @7='aaaaaaaaaaaaaaaaaaaa' /* VARSTRING(20) meta=20 nullable=1 is_null=0 */
+### @8='aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' /* BLOB/TEXT meta=2 nullable=1 is_null=0 */
+### INSERT INTO `test`.`t1`
+### SET
+### @1=100 /* TINYINT meta=0 nullable=1 is_null=0 */
+### @2=2 /* SHORTINT meta=0 nullable=1 is_null=0 */
+### @3=3 /* MEDIUMINT meta=0 nullable=1 is_null=0 */
+### @4=4 /* INT meta=0 nullable=1 is_null=0 */
+### @5=5 /* LONGINT meta=0 nullable=1 is_null=0 */
+### @6='abc' /* STRING(10) meta=65034 nullable=1 is_null=0 */
+### @7='abcdefg' /* VARSTRING(20) meta=20 nullable=1 is_null=0 */
+### @8='abcedfghijklmnopqrstuvwxyz' /* BLOB/TEXT meta=2 nullable=1 is_null=0 */
+### INSERT INTO `test`.`t1`
+### SET
+### @1=100 /* TINYINT meta=0 nullable=1 is_null=0 */
+### @2=0 /* SHORTINT meta=0 nullable=1 is_null=0 */
+### @3=0 /* MEDIUMINT meta=0 nullable=1 is_null=0 */
+### @4=0 /* INT meta=0 nullable=1 is_null=0 */
+### @5=0 /* LONGINT meta=0 nullable=1 is_null=0 */
+### @6='' /* STRING(10) meta=65034 nullable=1 is_null=0 */
+### @7='' /* VARSTRING(20) meta=20 nullable=1 is_null=0 */
+### @8='' /* BLOB/TEXT meta=2 nullable=1 is_null=0 */
+COMMIT
+/*!*/;
+#010909 9:46:40 server id 1 end_log_pos # CRC32 XXX Xid = #
+BEGIN/*!*/;
+#010909 9:46:40 server id 1 end_log_pos # CRC32 XXX Update_rows: table id # flags: STMT_END_F
+### UPDATE `test`.`t1`
+### WHERE
+### @1=100 /* TINYINT meta=0 nullable=1 is_null=0 */
+### @2=2 /* SHORTINT meta=0 nullable=1 is_null=0 */
+### @3=3 /* MEDIUMINT meta=0 nullable=1 is_null=0 */
+### @4=4 /* INT meta=0 nullable=1 is_null=0 */
+### @5=5 /* LONGINT meta=0 nullable=1 is_null=0 */
+### @6='abc' /* STRING(10) meta=65034 nullable=1 is_null=0 */
+### @7='abcdefg' /* VARSTRING(20) meta=20 nullable=1 is_null=0 */
+### @8='abcedfghijklmnopqrstuvwxyz' /* BLOB/TEXT meta=2 nullable=1 is_null=0 */
+### SET
+### @1=1 /* TINYINT meta=0 nullable=1 is_null=0 */
+### @2=2 /* SHORTINT meta=0 nullable=1 is_null=0 */
+### @3=3 /* MEDIUMINT meta=0 nullable=1 is_null=0 */
+### @4=4 /* INT meta=0 nullable=1 is_null=0 */
+### @5=5 /* LONGINT meta=0 nullable=1 is_null=0 */
+### @6='abc' /* STRING(10) meta=65034 nullable=1 is_null=0 */
+### @7='abcdefg' /* VARSTRING(20) meta=20 nullable=1 is_null=0 */
+### @8='abcedfghijklmnopqrstuvwxyz' /* BLOB/TEXT meta=2 nullable=1 is_null=0 */
+### UPDATE `test`.`t1`
+### WHERE
+### @1=100 /* TINYINT meta=0 nullable=1 is_null=0 */
+### @2=0 /* SHORTINT meta=0 nullable=1 is_null=0 */
+### @3=0 /* MEDIUMINT meta=0 nullable=1 is_null=0 */
+### @4=0 /* INT meta=0 nullable=1 is_null=0 */
+### @5=0 /* LONGINT meta=0 nullable=1 is_null=0 */
+### @6='' /* STRING(10) meta=65034 nullable=1 is_null=0 */
+### @7='' /* VARSTRING(20) meta=20 nullable=1 is_null=0 */
+### @8='' /* BLOB/TEXT meta=2 nullable=1 is_null=0 */
+### SET
+### @1=0 /* TINYINT meta=0 nullable=1 is_null=0 */
+### @2=0 /* SHORTINT meta=0 nullable=1 is_null=0 */
+### @3=0 /* MEDIUMINT meta=0 nullable=1 is_null=0 */
+### @4=0 /* INT meta=0 nullable=1 is_null=0 */
+### @5=0 /* LONGINT meta=0 nullable=1 is_null=0 */
+### @6='' /* STRING(10) meta=65034 nullable=1 is_null=0 */
+### @7='' /* VARSTRING(20) meta=20 nullable=1 is_null=0 */
+### @8='' /* BLOB/TEXT meta=2 nullable=1 is_null=0 */
+COMMIT
+/*!*/;
+#010909 9:46:40 server id 1 end_log_pos # CRC32 XXX Xid = #
+BEGIN/*!*/;
+#010909 9:46:40 server id 1 end_log_pos # CRC32 XXX Delete_rows: table id # flags: STMT_END_F
+### DELETE FROM `test`.`t1`
+### WHERE
+### @1=127 /* TINYINT meta=0 nullable=1 is_null=0 */
+### @2=32767 /* SHORTINT meta=0 nullable=1 is_null=0 */
+### @3=8388607 /* MEDIUMINT meta=0 nullable=1 is_null=0 */
+### @4=2147483647 /* INT meta=0 nullable=1 is_null=0 */
+### @5=9223372036854775807 /* LONGINT meta=0 nullable=1 is_null=0 */
+### @6='aaaaaaaaaa' /* STRING(10) meta=65034 nullable=1 is_null=0 */
+### @7='aaaaaaaaaaaaaaaaaaaa' /* VARSTRING(20) meta=20 nullable=1 is_null=0 */
+### @8='aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' /* BLOB/TEXT meta=2 nullable=1 is_null=0 */
+COMMIT
+/*!*/;
+#010909 9:46:40 server id 1 end_log_pos # CRC32 XXX Xid = #
+BEGIN/*!*/;
+#010909 9:46:40 server id 1 end_log_pos # CRC32 XXX Delete_rows: table id # flags: STMT_END_F
+### DELETE FROM `test`.`t1`
+### WHERE
+### @1=1 /* TINYINT meta=0 nullable=1 is_null=0 */
+### @2=2 /* SHORTINT meta=0 nullable=1 is_null=0 */
+### @3=3 /* MEDIUMINT meta=0 nullable=1 is_null=0 */
+### @4=4 /* INT meta=0 nullable=1 is_null=0 */
+### @5=5 /* LONGINT meta=0 nullable=1 is_null=0 */
+### @6='abc' /* STRING(10) meta=65034 nullable=1 is_null=0 */
+### @7='abcdefg' /* VARSTRING(20) meta=20 nullable=1 is_null=0 */
+### @8='abcedfghijklmnopqrstuvwxyz' /* BLOB/TEXT meta=2 nullable=1 is_null=0 */
+COMMIT
+/*!*/;
+#010909 9:46:40 server id 1 end_log_pos # CRC32 XXX Xid = #
+BEGIN/*!*/;
+#010909 9:46:40 server id 1 end_log_pos # CRC32 XXX Delete_rows: table id # flags: STMT_END_F
+### DELETE FROM `test`.`t1`
+### WHERE
+### @1=0 /* TINYINT meta=0 nullable=1 is_null=0 */
+### @2=0 /* SHORTINT meta=0 nullable=1 is_null=0 */
+### @3=0 /* MEDIUMINT meta=0 nullable=1 is_null=0 */
+### @4=0 /* INT meta=0 nullable=1 is_null=0 */
+### @5=0 /* LONGINT meta=0 nullable=1 is_null=0 */
+### @6='' /* STRING(10) meta=65034 nullable=1 is_null=0 */
+### @7='' /* VARSTRING(20) meta=20 nullable=1 is_null=0 */
+### @8='' /* BLOB/TEXT meta=2 nullable=1 is_null=0 */
+COMMIT
+/*!*/;
+#010909 9:46:40 server id 1 end_log_pos # CRC32 XXX Query thread_id=# exec_time=# error_code=0
+use `test`/*!*/;
+SET TIMESTAMP=1000000000/*!*/;
+SET @@session.pseudo_thread_id=#/*!*/;
+SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=0, @@session.unique_checks=1, @@session.autocommit=1, @@session.check_constraint_checks=1/*!*/;
+SET @@session.sql_mode=1342177280/*!*/;
+SET @@session.auto_increment_increment=1, @@session.auto_increment_offset=1/*!*/;
+/*!\C latin1 *//*!*/;
+SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8/*!*/;
+SET @@session.lc_time_names=0/*!*/;
+SET @@session.collation_database=DEFAULT/*!*/;
+COMMIT
+/*!*/;
+DELIMITER ;
+# End of log file
+ROLLBACK /* added by mysqlbinlog */;
+/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
+/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;
+#
+# Insert data to t1
+#
+TRUNCATE TABLE t1;
+INSERT INTO t1 VALUES(0,0,0,0,0,'','','');
+INSERT INTO t1 VALUES(1,2,3,4,5, "abc", "abcdefg", "abcedfghijklmnopqrstuvwxyz");
+INSERT INTO t1 VALUES(127, 32767, 8388607, 2147483647, 9223372036854775807, repeat('a', 10), repeat('a', 20), repeat('a', 60));
+#
+# Delete all existing binary logs.
+#
+RESET MASTER;
+SELECT * FROM t1;
+c01 c02 c03 c04 c05 c06 c07 c08
+0 0 0 0 0
+1 2 3 4 5 abc abcdefg abcedfghijklmnopqrstuvwxyz
+127 32767 8388607 2147483647 9223372036854775807 aaaaaaaaaa aaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+#
+# Operate some data
+#
+UPDATE t1 SET c01=20;
+UPDATE t1 SET c02=200;
+UPDATE t1 SET c03=2000;
+DELETE FROM t1;
+FLUSH LOGS;
+#
+# Flashback & Check the result
+#
+SELECT * FROM t1;
+c01 c02 c03 c04 c05 c06 c07 c08
+127 32767 8388607 2147483647 9223372036854775807 aaaaaaaaaa aaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+1 2 3 4 5 abc abcdefg abcedfghijklmnopqrstuvwxyz
+0 0 0 0 0
+RESET MASTER;
+#
+# UPDATE multi-rows in one event
+#
+BEGIN;
+UPDATE t1 SET c01=10 WHERE c01=0;
+UPDATE t1 SET c01=20 WHERE c01=10;
+COMMIT;
+FLUSH LOGS;
+#
+# Flashback & Check the result
+#
+SELECT * FROM t1;
+c01 c02 c03 c04 c05 c06 c07 c08
+127 32767 8388607 2147483647 9223372036854775807 aaaaaaaaaa aaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+1 2 3 4 5 abc abcdefg abcedfghijklmnopqrstuvwxyz
+0 0 0 0 0
+DROP TABLE t1;
+#
+# Self-referencing foreign keys
+#
+CREATE TABLE t1 (a INT PRIMARY KEY, b INT, FOREIGN KEY my_fk(b) REFERENCES t1(a)) ENGINE=InnoDB;
+BEGIN;
+INSERT INTO t1 VALUES (1, NULL);
+INSERT INTO t1 VALUES (2, 1), (3, 2), (4, 3);
+COMMIT;
+SELECT * FROM t1;
+a b
+1 NULL
+2 1
+3 2
+4 3
+RESET MASTER;
+DELETE FROM t1 ORDER BY a DESC;
+FLUSH LOGS;
+#
+# Flashback & Check the result
+#
+SELECT * FROM t1;
+a b
+1 NULL
+2 1
+3 2
+4 3
+DROP TABLE t1;
diff --git a/mysql-test/suite/binlog/t/flashback-master.opt b/mysql-test/suite/binlog/t/flashback-master.opt
new file mode 100644
index 00000000000..476efbe20ab
--- /dev/null
+++ b/mysql-test/suite/binlog/t/flashback-master.opt
@@ -0,0 +1,2 @@
+--flashback
+--timezone=GMT-8
diff --git a/mysql-test/suite/binlog/t/flashback.test b/mysql-test/suite/binlog/t/flashback.test
new file mode 100644
index 00000000000..2f395a2a7b1
--- /dev/null
+++ b/mysql-test/suite/binlog/t/flashback.test
@@ -0,0 +1,163 @@
+--source include/have_log_bin.inc
+--source include/have_innodb.inc
+
+--echo #
+--echo # Preparatory cleanup.
+--echo #
+--disable_warnings
+DROP TABLE IF EXISTS t1;
+--enable_warnings
+
+--echo #
+--echo # We need a fixed timestamp to avoid varying results.
+--echo #
+SET timestamp=1000000000;
+
+--echo #
+--echo # Delete all existing binary logs.
+--echo #
+RESET MASTER;
+
+
+CREATE TABLE t1 (
+ c01 tinyint,
+ c02 smallint,
+ c03 mediumint,
+ c04 int,
+ c05 bigint,
+ c06 char(10),
+ c07 varchar(20),
+ c08 TEXT
+) ENGINE=InnoDB;
+
+--echo #
+--echo # Insert data to t1
+--echo #
+INSERT INTO t1 VALUES(0,0,0,0,0,'','','');
+INSERT INTO t1 VALUES(1,2,3,4,5, "abc", "abcdefg", "abcedfghijklmnopqrstuvwxyz");
+INSERT INTO t1 VALUES(127, 32767, 8388607, 2147483647, 9223372036854775807, repeat('a', 10), repeat('a', 20), repeat('a', 255));
+
+
+--echo #
+--echo # Update t1
+--echo #
+UPDATE t1 SET c01=100 WHERE c02=0 OR c03=3;
+
+--echo #
+--echo # Clear t1
+--echo #
+DELETE FROM t1;
+
+FLUSH LOGS;
+
+--echo #
+--echo # Show mysqlbinlog result without -B
+--echo #
+
+let $MYSQLD_DATADIR= `select @@datadir`;
+--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
+--replace_regex /SQL_LOAD_MB-[0-9]-[0-9]/SQL_LOAD_MB-#-#/ /exec_time=[0-9]*/exec_time=#/ /end_log_pos [0-9]*/end_log_pos #/ /# at [0-9]*/# at #/ /Xid = [0-9]*/Xid = #/ /thread_id=[0-9]*/thread_id=#/ /table id [0-9]*/table id #/ /mapped to number [0-9]*/mapped to number #/ /server v [^ ]*/server v #.##.##/ /CRC32 0x[0-9a-f]*/CRC32 XXX/
+--exec $MYSQL_BINLOG --base64-output=decode-rows -v -v $MYSQLD_DATADIR/master-bin.000001
+
+--echo #
+--echo # Show mysqlbinlog result with -B
+--echo #
+
+let $MYSQLD_DATADIR= `select @@datadir`;
+--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
+--replace_regex /SQL_LOAD_MB-[0-9]-[0-9]/SQL_LOAD_MB-#-#/ /exec_time=[0-9]*/exec_time=#/ /end_log_pos [0-9]*/end_log_pos #/ /# at [0-9]*/# at #/ /Xid = [0-9]*/Xid = #/ /thread_id=[0-9]*/thread_id=#/ /table id [0-9]*/table id #/ /mapped to number [0-9]*/mapped to number #/ /server v [^ ]*/server v #.##.##/ /CRC32 0x[0-9a-f]*/CRC32 XXX/
+--exec $MYSQL_BINLOG -B --base64-output=decode-rows -v -v $MYSQLD_DATADIR/master-bin.000001
+
+--echo #
+--echo # Insert data to t1
+--echo #
+TRUNCATE TABLE t1;
+INSERT INTO t1 VALUES(0,0,0,0,0,'','','');
+INSERT INTO t1 VALUES(1,2,3,4,5, "abc", "abcdefg", "abcedfghijklmnopqrstuvwxyz");
+INSERT INTO t1 VALUES(127, 32767, 8388607, 2147483647, 9223372036854775807, repeat('a', 10), repeat('a', 20), repeat('a', 60));
+
+--echo #
+--echo # Delete all existing binary logs.
+--echo #
+RESET MASTER;
+SELECT * FROM t1;
+
+--echo #
+--echo # Operate some data
+--echo #
+
+UPDATE t1 SET c01=20;
+UPDATE t1 SET c02=200;
+UPDATE t1 SET c03=2000;
+
+DELETE FROM t1;
+
+FLUSH LOGS;
+
+--echo #
+--echo # Flashback & Check the result
+--echo #
+
+let $MYSQLD_DATADIR= `select @@datadir`;
+--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
+--exec $MYSQL_BINLOG -B -vv $MYSQLD_DATADIR/master-bin.000001 > $MYSQLTEST_VARDIR/tmp/mysqlbinlog_row_flashback_1.sql
+--exec $MYSQL -e "SET binlog_format= ROW; source $MYSQLTEST_VARDIR/tmp/mysqlbinlog_row_flashback_1.sql;"
+
+SELECT * FROM t1;
+
+RESET MASTER;
+
+--echo #
+--echo # UPDATE multi-rows in one event
+--echo #
+BEGIN;
+UPDATE t1 SET c01=10 WHERE c01=0;
+UPDATE t1 SET c01=20 WHERE c01=10;
+COMMIT;
+
+FLUSH LOGS;
+
+--echo #
+--echo # Flashback & Check the result
+--echo #
+
+let $MYSQLD_DATADIR= `select @@datadir`;
+--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
+--exec $MYSQL_BINLOG -B -vv $MYSQLD_DATADIR/master-bin.000001 > $MYSQLTEST_VARDIR/tmp/mysqlbinlog_row_flashback_2.sql
+--exec $MYSQL -e "SET binlog_format= ROW; source $MYSQLTEST_VARDIR/tmp/mysqlbinlog_row_flashback_2.sql;"
+
+SELECT * FROM t1;
+
+DROP TABLE t1;
+
+--echo #
+--echo # Self-referencing foreign keys
+--echo #
+CREATE TABLE t1 (a INT PRIMARY KEY, b INT, FOREIGN KEY my_fk(b) REFERENCES t1(a)) ENGINE=InnoDB;
+
+BEGIN;
+INSERT INTO t1 VALUES (1, NULL);
+INSERT INTO t1 VALUES (2, 1), (3, 2), (4, 3);
+COMMIT;
+
+SELECT * FROM t1;
+
+# New binlog
+RESET MASTER;
+
+DELETE FROM t1 ORDER BY a DESC;
+
+FLUSH LOGS;
+
+--echo #
+--echo # Flashback & Check the result
+--echo #
+
+let $MYSQLD_DATADIR= `select @@datadir`;
+--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
+--exec $MYSQL_BINLOG -B -vv $MYSQLD_DATADIR/master-bin.000001 > $MYSQLTEST_VARDIR/tmp/mysqlbinlog_row_flashback_3.sql
+--exec $MYSQL -e "SET binlog_format= ROW; source $MYSQLTEST_VARDIR/tmp/mysqlbinlog_row_flashback_3.sql;"
+
+SELECT * FROM t1;
+
+DROP TABLE t1;