10.2からバイナリログを逆さにするflashbackという機能が追加されたのですが、中々実践でためす機会もなかったので、改めて動きを確認してみます。
確認したバージョンは、10.5.5です。
(前提)
以下のようなテーブルを作成し、データと投入します。
MariaDB [test]> show create table fb;
+-------+-----------------------------------------------------------------------------------------------------------------------------------+
| Table | Create Table |
+-------+-----------------------------------------------------------------------------------------------------------------------------------+
| fb | CREATE TABLE fb
(
no int(11) NOT NULL,
name text NOT NULL,
PRIMARY KEY (no)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 |
+-------+-----------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.000 sec)
MariaDB [test]> insert into fb value (1, 'あああ');
Query OK, 1 row affected (0.003 sec)
MariaDB [test]> select * from fb;
+----+-----------+
| no | name |
+----+-----------+
| 1 | あああ |
+----+-----------+
1 row in set (0.001 sec)
GTIDとバイナリログを確認します。
MariaDB [test]> show variables like 'gtid_binlog_pos'; +-------------------------+------------+ | Variable_name | Value | +-------------------------+------------+ | gtid_binlog_pos | 0-1-284795 | +-------------------------+------------+ 1 rows in set (0.001 sec) MariaDB [test]> show binary logs; +------------------+-----------+ | Log_name | File_size | +------------------+-----------+ | mysql-bin.000066 | 54405979 | | mysql-bin.000067 | 9650 | | mysql-bin.000068 | 2667 | +------------------+-----------+ 3 rows in set (0.000 sec)
わかりやすくするために、一度バイナリログをflushします。
MariaDB [test]> flush binary logs; Query OK, 0 rows affected (0.005 sec) MariaDB [test]> show binary logs; +------------------+-----------+ | Log_name | File_size | +------------------+-----------+ | mysql-bin.000066 | 54405979 | | mysql-bin.000067 | 9650 | | mysql-bin.000068 | 2714 | | mysql-bin.000069 | 385 | +------------------+-----------+ 4 rows in set (0.000 sec)
一応、GTID確認します。
MariaDB [test]> show variables like 'gtid_binlog_pos'; +-------------------------+------------+ | Variable_name | Value | +-------------------------+------------+ | gtid_binlog_pos | 0-1-284795 | +-------------------------+------------+ 1 rows in set (0.001 sec)
GTIDは「0-1-284795」のままですね。
(データ追加)
データを追加し、GTIDを確認します。
MariaDB [test]> insert into fb value (2, 'いいい'); Query OK, 1 row affected (0.003 sec) MariaDB [test]> select * from fb; +----+-----------+ | no | name | +----+-----------+ | 1 | あああ | | 2 | いいい | +----+-----------+ 2 rows in set (0.000 sec) MariaDB [test]> show variables like 'gtid_binlog_pos'; +-------------------------+------------+ | Variable_name | Value | +-------------------------+------------+ | gtid_binlog_pos | 0-1-284796 | +-------------------------+------------+ 1 rows in set (0.001 sec)
GTIDが「0-1-284796」に変わりました。ここで、バイナリログを見てみます。長いので、一部だけにします。
# mysqlbinlog --no-defaults -vvv /var/lib/mysql/mysql-bin.000069 : : # at 256 #210224 11:08:36 server id 1 end_log_pos 299 CRC32 0xacff8998 Gtid list [0-1-284795] # at 299 #210224 11:08:36 server id 1 end_log_pos 342 CRC32 0x8bf7cf8a Binlog checkpoint mysql-bin.000068 # at 342 #210224 11:08:36 server id 1 end_log_pos 385 CRC32 0x187e7066 Binlog checkpoint mysql-bin.000069 # at 385 #210224 11:09:30 server id 1 end_log_pos 427 CRC32 0x5386bf8e GTID 0-1-284796 trans /*!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=284796*//*!*/; START TRANSACTION /*!*/; # at 427 # at 487 #210224 11:09:30 server id 1 end_log_pos 487 CRC32 0x685176b0 Annotate_rows: #Q> insert into fb value (2, 'いいい') #210224 11:09:30 server id 1 end_log_pos 534 CRC32 0x02e81a93 Table_map: `test`.`fb` mapped to number 64 # at 534 #210224 11:09:30 server id 1 end_log_pos 583 CRC32 0x9a15a3b4 Write_rows: table id 64 flags: STMT_END_F BINLOG ' WrU1YBMBAAAALwAAABYCAAAAAEAAAAAAAAEABHRlc3QAAmZiAAID/AECAJMa6AI= WrU1YBcBAAAAMQAAAEcCAAAAAEAAAAAAAAEAAv/8AgAAAAkA44GE44GE44GEtKMVmg== '/*!*/; ### INSERT INTO `test`.`fb` ### SET ### @1=2 /* INT meta=0 nullable=0 is_null=0 */ ### @2='いいい' /* BLOB/TEXT meta=2 nullable=0 is_null=0 */ # Number of rows: 1 # at 583 #210224 11:09:30 server id 1 end_log_pos 614 CRC32 0x2ae1c8a4 Xid = 4087358 COMMIT/*!*/; DELIMITER ; : :
まずは、「# at 256」を見てみます。
# at 256 #210224 11:08:36 server id 1 end_log_pos 299 CRC32 0xacff8998 Gtid list [0-1-284795]
listされたGTIDが「0-1-284795」になっているので、ここが直前のGTIDであり、
insert into fb value (1, 'あああ');
の直後となっています。
念の為、確認します。
MariaDB [test]> select binlog_gtid_pos('mysql-bin.000069', 256); +------------------------------------------+ | binlog_gtid_pos('mysql-bin.000069', 256) | +------------------------------------------+ | 0-1-284795 | +------------------------------------------+ 1 row in set (0.001 sec)
次に、「# at 385」を見てみます。
# at 385 #210224 11:09:30 server id 1 end_log_pos 427 CRC32 0x5386bf8e GTID 0-1-284796 trans
385からが、次のGTIDの開始点となります。そこから直近のCOMMITまでを追っていくと、
# at 583 #210224 11:09:30 server id 1 end_log_pos 614 CRC32 0x2ae1c8a4 Xid = 4087358 COMMIT/*!*/;
583に辿り着きます。583のGTIDを確認します。
MariaDB [test]> select binlog_gtid_pos('mysql-bin.000069', 583); +------------------------------------------+ | binlog_gtid_pos('mysql-bin.000069', 583) | +------------------------------------------+ | 0-1-284796 | +------------------------------------------+ 1 row in set (0.001 sec)
ここまでを整理すると、
GTID:「0-1-284795」(ポジション:「256」)は「(1, ‘あああ’)」の直後、
GTID:「0-1-284796」(ポジション:「583」)は「(2, ‘いいい’)」の直後、
となります。
※正確には、256を示すend_log_posのatが、1つ前のポジションです。
(操作取消)
では、GTID:「0-1-284796」の操作を取り消します。
# mysqlbinlog --no-defaults -vvv /var/lib/mysql/mysql-bin.000069 --start-position=256 --stop-position=583 --flashback /*!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 /*!*/; #210224 11:08:36 server id 1 end_log_pos 256 CRC32 0x9b36958f Start: binlog v 4, server v 10.5.5-MariaDB-log created 210224 11:08:36 # Warning: this binlog is either in use or was not closed properly. BINLOG ' JLU1YA8BAAAA/AAAAAABAAABAAQAMTAuNS41LU1hcmlhREItbG9nAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAEzgNAAgAEgAEBAQEEgAA5AAEGggAAAAICAgCAAAACgoKAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAEEwQADQgICAoKCgGPlTab '/*!*/; #210224 11:08:36 server id 1 end_log_pos 299 CRC32 0xacff8998 Gtid list [0-1-284795] #210224 11:08:36 server id 1 end_log_pos 342 CRC32 0x8bf7cf8a Binlog checkpoint mysql-bin.000068 #210224 11:08:36 server id 1 end_log_pos 385 CRC32 0x187e7066 Binlog checkpoint mysql-bin.000069 #210224 11:09:30 server id 1 end_log_pos 487 CRC32 0x685176b0 Annotate_rows: #Q> insert into fb value (2, 'いいい') #210224 11:09:30 server id 1 end_log_pos 534 CRC32 0x02e81a93 Table_map: `test`.`fb` mapped to number 64 # Number of rows: 1 #210224 11:09:30 server id 1 end_log_pos 583 CRC32 0x9a15a3b4 Delete_rows: table id 64 flags: STMT_END_F BINLOG ' WrU1YBMBAAAALwAAABYCAAAAAEAAAAAAAAEABHRlc3QAAmZiAAID/AECAJMa6AI= WrU1YBkBAAAAMQAAAEcCAAAAAEAAAAAAAAEAAv/8AgAAAAkA44GE44GE44GEtKMVmg== '/*!*/; ### DELETE FROM `test`.`fb` ### WHERE ### @1=2 /* INT meta=0 nullable=0 is_null=0 */ ### @2='いいい' /* BLOB/TEXT meta=2 nullable=0 is_null=0 */ COMMIT /*!*/; COMMIT /*!*/; DELIMITER ; # End of log file ROLLBACK /* added by mysqlbinlog */; /*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/; /*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;
これをファイルに落として、実行することで、「(2, ‘いいい’)」のINSERTが取り消されます。ただし、バイナリログには、別途GTIDが切り出されます。
長くなりましたが、
start-positionの部分には、”戻したい場所”にしましょう。
今回では、
Gtid list [0-1-284795]
の箇所が直前のGTID払い出し位置となるので、ここに戻すようにしています。
MariaDBだと、GTIDで状態を確認することが多いので、flashbackでもGTIDの状態をみるように注意して対応してみました。
以上
コメントがあればどうぞ