MySQLbinlog日誌02binlog日誌用於數據恢復
本系列博客主要介紹MySQL數據庫的binlog日誌的相關內容,這個系列的主題包括:
MySQLbinlog日誌01binlog日誌基本操作
MySQLbinlog日誌02binlog日誌用於數據恢復
MySQLbinlog日誌03binlog日誌字節碼解析
MySQLbinlog日誌04binlog日誌字節碼解析之二Write_Rows事件
本博客主要內容如下:
binlog日誌的記錄次序
binlog日誌恢復數據
binlog數據庫閃回工具myfash
1. binlog日誌的記錄次序
binlog日誌是在事務提交時才寫入到binlog日誌文件中的,這就決定了binlog日誌文件中的事件記錄的次序由所在的事務提交的時間點的次序決定,而不是由
按照以下操作可以驗證上述結論。
先建立一個表:
mysql> create table t5 (id int auto_increment primary key, who varchar (10) , time timestamp default current_timestamp on update current_timestamp );
Query OK, 0 rows affected (0.01 sec)
其中id字段表示記錄被添加的次序,
時間次序 |
事務A |
事務B |
1 |
begin; |
|
2 |
insert into t5 (who) values (‘A‘); |
|
3 |
|
begin; |
4 |
|
insert into t5 (who) values (‘B‘); |
5 |
insert into t5 (who) values (‘A‘); |
|
6 |
|
insert into t5 (who) values (‘B‘); |
7 |
|
commit; |
8 |
insert into t5 (who) values (‘A‘); |
|
9 |
commit; |
|
執行結果如下:
mysql> select * from t5;
+----+------+---------------------+
| id | who | time |
+----+------+---------------------+
| 1 | A | 2018-09-20 22:05:25 |
| 2 | B | 2018-09-20 22:06:11 |
| 3 | A | 2018-09-20 22:06:51 |
| 4 | B | 2018-09-20 22:07:00 |
| 5 | A | 2018-09-20 22:07:21 |
+----+------+---------------------+
5 rows in set (0.00 sec)
查看binlog事件信息:
使用以下命令也可以查看到這兩個事務的全部binlog事件信息,同樣可以觀察到這個現象。
mysqlbinlog --base64-output=DECODE-ROWS mysql_binlog.000003 -vv
也可以使用以下的命令僅僅查看binlog文件中的SQL語句信息(這些SQL語句不是通常的SQL語句,有比較獨特的語法,不能獨立執行):
[root@101 binlog]# mysqlbinlog -v --base64-output=DECODE-ROWS mysql_binlog.000003 |grep -E -v "^\/\*" |grep -E "^(###)|(COMMIT)"|sed ‘s/^### //g‘
INSERT INTO `binlog`.`t5`
SET
@1=2
@2=‘B‘
@3=1537452371
INSERT INTO `binlog`.`t5`
SET
@1=4
@2=‘B‘
@3=1537452420
COMMIT/*!*/;
INSERT INTO `binlog`.`t5`
SET
@1=1
@2=‘A‘
@3=1537452325
INSERT INTO `binlog`.`t5`
SET
@1=3
@2=‘A‘
@3=1537452411
INSERT INTO `binlog`.`t5`
SET
@1=5
@2=‘A‘
@3=1537452441
COMMIT/*!*/;
可以看到事務B的全部事件排列在前面,然後才是事務A的全部事件。事務A內部的各個事件按照執行的時間次序排列,事務B也是。
經過實際驗證,這個次序跟事務隔離級別沒有關系,在READ COMMITTED和REPEATABLE READ隔離級別下都是相同的結果。
通過這個操作過程,可以得出3個結論:
(1)事務提交的次序決定事務的事件數據在binlog日誌文件中的先後次序,
(2)事務內部的所有事件集中在一起,不同事務的事件不會交叉出現在binlog日誌文件中。
(3)事務內部的所有事件按照時間次序排列。
2. binlog日誌恢復數據
假設先執行了以下的操作:
mysql> desc t7;
+-------+-------------+------+-----+-------------------+-----------------------------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------+------+-----+-------------------+-----------------------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| who | varchar(10) | YES | | NULL | |
| time | timestamp | YES | | CURRENT_TIMESTAMP | on update CURRENT_TIMESTAMP |
+-------+-------------+------+-----+-------------------+-----------------------------+
3 rows in set (0.01 sec)
mysql> insert into t7 (who) values (‘A1‘);
Query OK, 1 row affected (0.01 sec)
mysql> insert into t7 (who) values (‘A2‘);
Query OK, 1 row affected (0.00 sec)
mysql> insert into t7 (who) values (‘A3‘);
Query OK, 1 row affected (0.01 sec)
mysql> insert into t7 (who) values (‘A4‘);
Query OK, 1 row affected (0.00 sec)
mysql> insert into t7 (who) values (‘A5‘);
Query OK, 1 row affected (0.00 sec)
mysql> insert into t7 (who) values (‘A6‘);
Query OK, 1 row affected (0.00 sec)
mysql> insert into t7 (who) values (‘A7‘);
Query OK, 1 row affected (0.01 sec)
mysql> insert into t7 (who) values (‘A8‘);
Query OK, 1 row affected (0.00 sec)
mysql> insert into t7 (who) values (‘A9‘);
Query OK, 1 row affected (0.00 sec)
mysql> insert into t7 (who) values (‘A10‘);
Query OK, 1 row affected (0.00 sec)
mysql> select * from t7;
+----+------+---------------------+
| id | who | time |
+----+------+---------------------+
| 1 | A1 | 2018-09-20 22:55:55 |
| 2 | A2 | 2018-09-20 22:55:57 |
| 3 | A3 | 2018-09-20 22:55:58 |
| 4 | A4 | 2018-09-20 22:56:06 |
| 5 | A5 | 2018-09-20 22:56:08 |
| 6 | A6 | 2018-09-20 22:56:39 |
| 7 | A7 | 2018-09-20 22:56:41 |
| 8 | A8 | 2018-09-20 22:56:43 |
| 9 | A9 | 2018-09-20 22:56:45 |
| 10 | A10 | 2018-09-20 22:56:47 |
+----+------+---------------------+
10 rows in set (0.00 sec)
mysql> create table t8 like t7;
Query OK, 0 rows affected (0.01 sec)
mysql> insert into t8 (who) values (‘B1‘);
Query OK, 1 row affected (0.02 sec)
mysql> insert into t8 (who) values (‘B2‘);
Query OK, 1 row affected (0.00 sec)
mysql> insert into t8 (who) values (‘B3‘);
Query OK, 1 row affected (0.00 sec)
mysql> insert into t8 (who) values (‘B4‘);
Query OK, 1 row affected (0.01 sec)
mysql> insert into t8 (who) values (‘B5‘);
Query OK, 1 row affected (0.00 sec)
mysql> insert into t7 (who) values (‘A100‘);
Query OK, 1 row affected (0.00 sec)
mysql> insert into t7 (who) values (‘A101‘);
Query OK, 1 row affected (0.00 sec)
mysql> select * from t8;
+----+------+---------------------+
| id | who | time |
+----+------+---------------------+
| 1 | B1 | 2018-09-20 22:57:24 |
| 2 | B2 | 2018-09-20 22:57:26 |
| 3 | B3 | 2018-09-20 22:57:28 |
| 4 | B4 | 2018-09-20 22:57:29 |
| 5 | B5 | 2018-09-20 22:57:31 |
+----+------+---------------------+
5 rows in set (0.00 sec)
此時t7和t8表中都有正常數據。
這時由於某種疏忽執行了以下的delete語句。
mysql> delete from t8;
Query OK, 5 rows affected (0.02 sec)
mysql> select * from t8;
Empty set (0.00 sec)
結果是t8表的全部數據都被刪除了。
現在的問題是需要恢復這些被刪除的數據。
使用binlog可以實現這個目標。
先找到當前使用的binlog文件名稱。
mysql> show binary logs;
+---------------------+-----------+
| Log_name | File_size |
+---------------------+-----------+
| mysql_binlog.000001 | 439 |
| mysql_binlog.000002 | 1149 |
| mysql_binlog.000003 | 1319 |
| mysql_binlog.000004 | 361 |
| mysql_binlog.000005 | 1319 |
| mysql_binlog.000006 | 6392 |
+---------------------+-----------+
6 rows in set (0.01 sec)
mysql> flush binary logs;
Query OK, 0 rows affected (0.01 sec)
執行之前那些數據增刪操作對應的事件記錄在mysql_binlog.000006文件中。
基本的思路是先找到binlog中對t8表的正常操作(insert)的binlog事件,不包括delete語句的事件,然後將這些事件在數據庫中重新執行一遍即可。先需要確定這些事件的位置範圍的開始位置和結束位置。
在binlog文件還存在的情況下,使用以下SQL語句查詢這個binlog文件中的事件。
mysql> show binlog events in ‘mysql_binlog.000006‘;
開始位置:
找到先前執行的t8表的第一個insert事件的開始位置。3805 (BEGIN)
結束位置:
找到先前執行的t8表的最後一個insert事件的結束位置。5375(COMMIT)
在3805到5375範圍內的binlog事件全部是t8的insert語句相關的事件。
使用mysqlbinlog提取這些事件產生SQL語句,並通過mysql程序執行提取的SQL語句。
[root@101 binlog]# mysqlbinlog --start-position=3805 --stop-position=5375 mysql_binlog.000006 |mysql -uroot -p123456 -S /tmp/mysql.sock
此時查看t8表的數據:
mysql> select * from t8;
+----+------+---------------------+
| id | who | time |
+----+------+---------------------+
| 1 | B1 | 2018-09-20 22:57:24 |
| 2 | B2 | 2018-09-20 22:57:26 |
| 3 | B3 | 2018-09-20 22:57:28 |
| 4 | B4 | 2018-09-20 22:57:29 |
| 5 | B5 | 2018-09-20 22:57:31 |
+----+------+---------------------+
5 rows in set (0.00 sec)
t8表的數據恢復成功。
在執行這個操作之前,可以先通過以下命令先產生SQL語句,確認無誤後再通過mysql程序導入數據。
mysqlbinlog --start-position=3805 --stop-position=5375 mysql_binlog.000006 -vv
可以同時指定位置範圍和時間戳範圍,這樣更準確的過濾數據,可以通過以下命令查看截取的數據。
mysqlbinlog --start-position=3805 --stop-position=5375 --start-datetime=20180920225724 --stop-datetime=20180920225732 -vv mysql_binlog.000006
確認無誤後同樣根據以下命令導入這部分數據到t8表中。
mysqlbinlog --start-position=3805 --stop-position=5375 --start-datetime=20180920225724 --stop-datetime=20180920225732 -vv mysql_binlog.000006 |mysql -uroot -p123456 -S /tmp/mysql.sock
這個簡單的方法的最大缺點是當這個範圍內包含有對其它數據表的操作時,這些操作將會影響到其它數據表。
mysqlbinlog還有一些參數:
--disable-log-bin :作用是本次操作不記錄binlog日誌。如果不希望本次操作影響到復制中的slave從機,則可以添加這個參數。
--database=XXXX:
在ROW模式下,作用是本次操作僅僅包含對XXXX數據庫的操作,跟是否使用use無關。
在SQL模式下,作用比較隱晦,此時最好都通過use語句指定數據庫,而不是通過數據庫名.表名的方式。
以下文字來自man mysqlbinlog的輸出信息:
mysqlbinlog --database=test does not output the first two INSERT statements because there is no default database. It outputs the three INSERT statements following USE test,
but not the three INSERT statements following USE db2.
mysqlbinlog --database=db2 does not output the first two INSERT statements because there is no default database. It does not output the three INSERT statements following USE
test, but does output the three INSERT statements following USE db2.
Row-based logging. mysqlbinlog outputs only entries that change tables belonging to db_name. The default database has no effect on this. Suppose that the binary log just
described was created using row-based logging rather than statement-based logging. mysqlbinlog --database=test outputs only those entries that modify t1 in the test database,
regardless of whether USE was issued or what the default database is. If a server is running with binlog_format set to MIXED and you want it to be possible to use mysqlbinlog
with the --database option, you must ensure that tables that are modified are in the database selected by USE. (In particular, no cross-database updates should be used.)
3. binlog數據庫閃回工具myfash
myflash是一款MySQL binlog數據庫閃回工具,核心機制是讀取binlog文件的INSERT/UPDATE?DELETE事件,並將這些事件的基礎上產生相應的逆向(回滾)事件,然後逆序保存到binlog文件中,最後執行這些binlog文件,從而達到數據庫快速回滾某一段時間範圍或者binlog位置範圍內的數據操作的目的。
flashback的參數指定的位置範圍和時間範圍是“誤操作”產生的事件數據的範圍,比如前面例子中的誤操作就是delete from t8這個SQL語句。因此需要找到這個語句。
通過以下SQL語句來查找,
mysql> show binlog events in ‘mysql_binlog.000006‘;
或者直接通過binlog文件來查找:
# at 6102
#180920 22:58:52 server id 101 end_log_pos 6176 CRC32 0x26716c36 Query thread_id=4 exec_time=0 error_code=0
SET TIMESTAMP=1537455532/*!*/;
BEGIN
/*!*/;
# at 6176
#180920 22:58:52 server id 101 end_log_pos 6214 CRC32 0x763a5d60 Rows_query
# delete from t8
# at 6214
#180920 22:58:52 server id 101 end_log_pos 6266 CRC32 0x33416fc0 Table_map: `binlog`.`t8` mapped to number 145
# at 6266
#180920 22:58:52 server id 101 end_log_pos 6361 CRC32 0xfe4e1cba Delete_rows: table id 145 flags: STMT_END_F
BINLOG ‘
rLWjWx1lAAAAJgAAAEYYAACAAA5kZWxldGUgZnJvbSB0OGBdOnY=
rLWjWxNlAAAANAAAAHoYAAAAAJEAAAAAAAEABmJpbmxvZwACdDgAAwMPEQMKAAAGwG9BMw==
rLWjWyBlAAAAXwAAANkYAAAAAJEAAAAAAAEAAgAD//gBAAAAAkIxW6O1VPgCAAAAAkIyW6O1VvgD
AAAAAkIzW6O1WPgEAAAAAkI0W6O1WfgFAAAAAkI1W6O1W7ocTv4=
‘/*!*/;
### DELETE FROM `binlog`.`t8`
### WHERE
### @1=1 /* INT meta=0 nullable=0 is_null=0 */
### @2=‘B1‘ /* VARSTRING(10) meta=10 nullable=1 is_null=0 */
### @3=1537455444 /* TIMESTAMP(0) meta=0 nullable=1 is_null=0 */
### DELETE FROM `binlog`.`t8`
### WHERE
### @1=2 /* INT meta=0 nullable=0 is_null=0 */
### @2=‘B2‘ /* VARSTRING(10) meta=10 nullable=1 is_null=0 */
### @3=1537455446 /* TIMESTAMP(0) meta=0 nullable=1 is_null=0 */
### DELETE FROM `binlog`.`t8`
### WHERE
### @1=3 /* INT meta=0 nullable=0 is_null=0 */
### @2=‘B3‘ /* VARSTRING(10) meta=10 nullable=1 is_null=0 */
### @3=1537455448 /* TIMESTAMP(0) meta=0 nullable=1 is_null=0 */
### DELETE FROM `binlog`.`t8`
### WHERE
### @1=4 /* INT meta=0 nullable=0 is_null=0 */
### @2=‘B4‘ /* VARSTRING(10) meta=10 nullable=1 is_null=0 */
### @3=1537455449 /* TIMESTAMP(0) meta=0 nullable=1 is_null=0 */
### DELETE FROM `binlog`.`t8`
### WHERE
### @1=5 /* INT meta=0 nullable=0 is_null=0 */
### @2=‘B5‘ /* VARSTRING(10) meta=10 nullable=1 is_null=0 */
### @3=1537455451 /* TIMESTAMP(0) meta=0 nullable=1 is_null=0 */
# at 6361
#180920 22:58:52 server id 101 end_log_pos 6392 CRC32 0xeb934c3d Xid = 295
COMMIT/*!*/;
最後找到的位置範圍是6102到6392,時間範圍180920 22:58:52到180920 22:58:52。
在此基礎上,可以執行flashback程序,產生對應的“回滾”binlog日誌文件。
root@101 binary]# ./flashback --databaseNames=binlog --tableNames=t8 --start-position=6102 --stop-position=6392 --start-datetime="2018-09-20 22:58:52" --stop-datetime="2018-09-20 22:58:52" --sqlTypes=delete --binlogFileNames=/opt/mysql/binlog/mysql_binlog.000006
產生的binlog日誌文件:
binlog_output_base.flashback
使用mysqlbinlog查看這個binlog日誌文件的內容:
[root@101 binary]# mysqlbinlog binlog_output_base.flashback -vv
/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/;
/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
DELIMITER /*!*/;
# at 4
#180920 22:45:53 server id 101 end_log_pos 123 CRC32 0x516e9591 Start: binlog v 4, server v 5.7.22-log created 180920 22:45:53
BINLOG ‘
obKjWw9lAAAAdwAAAHsAAAAAAAQANS43LjIyLWxvZwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAEzgNAAgAEgAEBAQEEgAAXwAEGggAAAAICAgCAAAACgoKKioAEjQA
AZGVblE=
‘/*!*/;
# at 123
#180920 22:58:52 server id 101 end_log_pos 175 CRC32 0x33416fc0 Table_map: `binlog`.`t8` mapped to number 145
# at 175
#180920 22:58:52 server id 101 end_log_pos 270 CRC32 0xfe4e1cba Write_rows: table id 145 flags: STMT_END_F
BINLOG ‘
rLWjWxNlAAAANAAAAK8AAAAAAJEAAAAAAAEABmJpbmxvZwACdDgAAwMPEQMKAAAGwG9BMw==
rLWjWx5lAAAAXwAAAA4BAAAAAJEAAAAAAAEAAgAD//gBAAAAAkIxW6O1VPgCAAAAAkIyW6O1VvgD
AAAAAkIzW6O1WPgEAAAAAkI0W6O1WfgFAAAAAkI1W6O1W7ocTv4=
‘/*!*/;
### INSERT INTO `binlog`.`t8`
### SET
### @1=1 /* INT meta=0 nullable=0 is_null=0 */
### @2=‘B1‘ /* VARSTRING(10) meta=10 nullable=1 is_null=0 */
### @3=1537455444 /* TIMESTAMP(0) meta=0 nullable=1 is_null=0 */
### INSERT INTO `binlog`.`t8`
### SET
### @1=2 /* INT meta=0 nullable=0 is_null=0 */
### @2=‘B2‘ /* VARSTRING(10) meta=10 nullable=1 is_null=0 */
### @3=1537455446 /* TIMESTAMP(0) meta=0 nullable=1 is_null=0 */
### INSERT INTO `binlog`.`t8`
### SET
### @1=3 /* INT meta=0 nullable=0 is_null=0 */
### @2=‘B3‘ /* VARSTRING(10) meta=10 nullable=1 is_null=0 */
### @3=1537455448 /* TIMESTAMP(0) meta=0 nullable=1 is_null=0 */
### INSERT INTO `binlog`.`t8`
### SET
### @1=4 /* INT meta=0 nullable=0 is_null=0 */
### @2=‘B4‘ /* VARSTRING(10) meta=10 nullable=1 is_null=0 */
### @3=1537455449 /* TIMESTAMP(0) meta=0 nullable=1 is_null=0 */
### INSERT INTO `binlog`.`t8`
### SET
### @1=5 /* INT meta=0 nullable=0 is_null=0 */
### @2=‘B5‘ /* VARSTRING(10) meta=10 nullable=1 is_null=0 */
### @3=1537455451 /* TIMESTAMP(0) meta=0 nullable=1 is_null=0 */
SET @@SESSION.GTID_NEXT= ‘AUTOMATIC‘ /* added by mysqlbinlog */ /*!*/;
DELIMITER ;
# End of log file
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;
總共包含了5條INSERT語句,正好插入5條數據記錄,從而可以借此達到“回滾”的目標。
最後通過mysqlbinlog產生對應的 SQL語句,並通過mysql程序執行,最終恢復了t8表的5條被誤操作刪除的記錄。
[root@101 binary]# mysqlbinlog -vv binlog_output_base.flashback |mysql -uroot -p123456 -S /tmp/mysql.sock
mysql> select * from t8;
+----+------+---------------------+
| id | who | time |
+----+------+---------------------+
| 1 | B1 | 2018-09-20 22:57:24 |
| 2 | B2 | 2018-09-20 22:57:26 |
| 3 | B3 | 2018-09-20 22:57:28 |
| 4 | B4 | 2018-09-20 22:57:29 |
| 5 | B5 | 2018-09-20 22:57:31 |
+----+------+---------------------+
5 rows in set (0.00 sec)
myflash工具的適用條件:
(1)binlog_format=row
如果binlog記錄sql語句而不是行記錄數據,那麽沒辦法僅僅根據一個sql語句產生反向的“回滾”binlog事件。因此不適用於STATEMENT模式或者MIXED模式。
在STATEMENT模式下,delete from t8對應的binlog數據的內容為:
BEGIN
/*!*/;
# at 302
#180921 0:54:48 server id 101 end_log_pos 394 CRC32 0x3cb196cf Query thread_id=2 exec_time=0 error_code=0
use `binlog`/*!*/;
SET TIMESTAMP=1537462488/*!*/;
delete from t8
/*!*/;
# at 394
#180921 0:54:48 server id 101 end_log_pos 425 CRC32 0xa4634f24 Xid = 21
COMMIT/*!*/;
沒有包含任何行記錄數據信息,因此myflash工具也沒法產生反向操作insert所需要的數據。
(2)binlog_row_image=full
如果binliog中記錄的行記錄中缺少一部分字段的值,則很可能沒辦法產生反向的“回滾”binlog事件。
在binlog_row_image=minimal的情況下,delete from t8產生的binlog事件如下:
# delete from t8
# at 331
#180921 0:35:08 server id 101 end_log_pos 383 CRC32 0x571c1559 Table_map: `binlog`.`t8` mapped to number 117
# at 383
#180921 0:35:08 server id 101 end_log_pos 443 CRC32 0xc220f346 Delete_rows: table id 117 flags: STMT_END_F
BINLOG ‘
PMyjWx1lAAAAJgAAAEsBAACAAA5kZWxldGUgZnJvbSB0OO9WEy8=
PMyjWxNlAAAANAAAAH8BAAAAAHUAAAAAAAEABmJpbmxvZwACdDgAAwMPEQMKAAAGWRUcVw==
PMyjWyBlAAAAPAAAALsBAAAAAHUAAAAAAAEAAgADAf4BAAAA/gIAAAD+AwAAAP4EAAAA/gUAAABG
8yDC
‘/*!*/;
### DELETE FROM `binlog`.`t8`
### WHERE
### @1=1 /* INT meta=0 nullable=0 is_null=0 */
### DELETE FROM `binlog`.`t8`
### WHERE
### @1=2 /* INT meta=0 nullable=0 is_null=0 */
### DELETE FROM `binlog`.`t8`
### WHERE
### @1=3 /* INT meta=0 nullable=0 is_null=0 */
### DELETE FROM `binlog`.`t8`
### WHERE
### @1=4 /* INT meta=0 nullable=0 is_null=0 */
### DELETE FROM `binlog`.`t8`
### WHERE
### @1=5 /* INT meta=0 nullable=0 is_null=0 */
其中的5條DELETE語句每個僅僅包含了主鍵字段id的值,而沒有包含其它的字段,此時myflash工具無法產生包含完整的原始字段數據的INSERT語句。
此時myflash工具產生的binlog數據如下:
### INSERT INTO `binlog`.`t8`
### SET
### @1=1 /* INT meta=0 nullable=0 is_null=0 */
### INSERT INTO `binlog`.`t8`
### SET
### @1=2 /* INT meta=0 nullable=0 is_null=0 */
### INSERT INTO `binlog`.`t8`
### SET
### @1=3 /* INT meta=0 nullable=0 is_null=0 */
### INSERT INTO `binlog`.`t8`
### SET
### @1=4 /* INT meta=0 nullable=0 is_null=0 */
### INSERT INTO `binlog`.`t8`
### SET
### @1=5 /* INT meta=0 nullable=0 is_null=0 */
依靠這個數據是沒法產生t8表的其它字段的數據的。
(3)只能是INSERT/DELETE/UPDATE這三種語句,而不能是DDL語句,也不能是TRUNCATE TABLE語句。
如果是DDL語句,則可能沒法產生反向的“回滾”binlog事件。TRUNCATE TABLE語句產生的binlog事件不包含行數據信息,因此也無法回滾。
MySQLbinlog日誌02binlog日誌用於數據恢復