啟用 binlog_format=ROW 後,DML 不再記錄為 Query_event,而是拆解為三類 **Row Event**:
Write_rows_event:INSERT,包含完整新行數據。Update_rows_event:UPDATE,包含 **修改前** 與 **修改後** 完整行數據(雙映像)。Delete_rows_event:DELETE,包含被刪除行的主鍵(無主鍵則全列)。每個 Row Event 前必有一個 Table_map_event,映射表內部 ID 與結構定義,故庫級複制規則與 STATEMENT 格式不同(不依賴 USE db)。
SET binlog_format=row; FLUSH LOGS; INSERT INTO test.t1 VALUES(1,'a'); INSERT INTO t1 VALUES(2,'b'); UPDATE t1 SET name='c' WHERE id=2; DELETE FROM t1 WHERE id=1;
Log_name Pos Event_type Server_id End_log_pos Info mysql-bin.000025 4 Format_desc 1 120 Server ver: 5.6.31-log ... 120 Query 1 188 BEGIN ... 188 Table_map 1 236 table_id: 79 (test.t1) ... 236 Write_rows 1 278 table_id: 79 flags: STMT_END_F ... 278 Xid 1 309 COMMIT ... 309 Query 1 381 BEGIN ... 381 Table_map 1 429 table_id: 79 (test.t1) ... 429 Write_rows 1 471 table_id: 79 flags: STMT_END_F ... 471 Xid 1 502 COMMIT ... 502 Query 1 574 BEGIN ... 574 Table_map 1 622 table_id: 79 (test.t1) ... 622 Update_rows 1 672 table_id: 79 flags: STMT_END_F ... 672 Xid 1 703 COMMIT ... 703 Query 1 775 BEGIN ... 775 Table_map 1 823 table_id: 79 (test.t1) ... 823 Delete_rows 1 865 table_id: 79 flags: STMT_END_F ... 865 Xid 1 896 COMMIT
直接執行 mysqlbinlog mysql-bin.000025 僅顯示 Base64 編碼的 Row Event,**無法看到原生 SQL**。
**正確姿勢**:
mysqlbinlog mysql-bin.000025 -vv --base64-output=decode-rows
-vv:Verbose 模式,解析 Row Event 為可讀的偽 SQL。--base64-output=decode-rows:將 Base64 行事件解碼並以註釋形式輸出。### INSERT INTO `test`.`t1` ### SET ### @1=1 /* INT meta=0 nullable=1 is_null=0 */ ### @2='a' /* VARSTRING(30) meta=30 nullable=1 is_null=0 */ ### UPDATE `test`.`t1` ### WHERE ### @1=2 /* INT meta=0 nullable=1 is_null=0 */ ### @2='b' /* VARSTRING(30) meta=30 nullable=1 is_null=0 */ ### SET ### @1=2 /* INT meta=0 nullable=1 is_null=0 */ ### @2='c' /* VARSTRING(30) meta=30 nullable=1 is_null=0 */ ### DELETE FROM `test`.`t1` ### WHERE ### @1=1 /* INT meta=0 nullable=1 is_null=0 */ ### @2='a' /* VARSTRING(30) meta=30 nullable=1 is_null=0 */
MySQL 5.6+ 提供參數 binlog_rows_query_log_events=1,在事務中插入 Rows_query_event,記錄原始 SQL 文本(**僅作註釋,不參與重放**)。
SET binlog_rows_query_log_events=1; INSERT INTO t1 VALUES(3,'c'); # SHOW BINLOG EVENTS 將顯示 Rows_query 事件: # # insert into t1 values(3,'c')
| 特性 | STATEMENT | ROW |
|---|---|---|
| Binlog 內容 | 原生 SQL 文本 | 行級變更數據(Base64) |
| 複制一致性 | 非確定性函數可能不一致 | 強一致,逐行重放 |
| Binlog 體積 | 小 | 大(含完整行數據) |
| 解析工具 | mysqlbinlog 直接可讀 | 需 -vv --base64-output=decode-rows |
| 原生 SQL 還原 | 原生即可見 | 開啟 binlog_rows_query_log_events=1 |
binlog_format=ROW(或 MIXED)保證複制一致性。mysqlbinlog -vv --base64-output=decode-rows。binlog_rows_query_log_events(微小性能開銷)。