首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 數據庫知識 >  >> MySQL 資料庫 >> MySQL 綜合教學

MySQL Binlog 事件類型深度解析:從 QUERY_EVENT 到 GTID_LOG_EVENT

     編輯:MySQL 綜合教學

MySQL Binlog 事件類型深度解析:從 QUERY_EVENT 到 GTID_LOG_EVENT

Binlog 記錄了資料庫所有變更,每筆變更對應一種事件類型。理解事件類型對於同步原理、增量恢復、審計分析至關重要。本文基於 MySQL 5.7 源碼(binlog_event.h),挑選核心事件類型詳細解析,並附 mysqlbinlog 與 SHOW BINLOG EVENTS 實際輸出對照。

一、核心事件類型枚舉(節選)

enum Log_event_type {
  UNKNOWN_EVENT = 0,
  START_EVENT_V3 = 1,
  QUERY_EVENT = 2,           -- 文本 SQL(BEGIN、DDL、STATEMENT 格式 DML)
  STOP_EVENT = 3,
  ROTATE_EVENT = 4,          -- binlog 切換
  INTVAR_EVENT = 5,
  FORMAT_DESCRIPTION_EVENT = 15,  -- binlog v4 首個事件,定義版本/建立時間
  XID_EVENT = 16,            -- 事務提交 (COMMIT)
  TABLE_MAP_EVENT = 19,      -- ROW 格式:表映射
  WRITE_ROWS_EVENT = 30,     -- ROW 格式 INSERT
  UPDATE_ROWS_EVENT = 31,    -- ROW 格式 UPDATE
  DELETE_ROWS_EVENT = 32,    -- ROW 格式 DELETE
  GTID_LOG_EVENT = 33,       -- GTID 事務標識
  ANONYMOUS_GTID_LOG_EVENT = 34,
  PREVIOUS_GTIDS_LOG_EVENT = 35,
  TRANSACTION_CONTEXT_EVENT = 36,
  XA_PREPARE_LOG_EVENT = 38,
  ENUM_END_EVENT
};

二、重點事件詳細解析

1. FORMAT_DESCRIPTION_EVENT(binlog 首事件)

每個 binlog 檔案第一個事件,僅出現一次。定義 binlog 版本、Server 版本、建立時間。MySQL 解析後續事件的基準。

# mysqlbinlog 輸出
# at 4
#160817 11:00:10 server id 1 end_log_pos 120 CRC32 0x03010da1
Start: binlog v 4, server v 5.6.31-log created 160817 11:00:10

2. QUERY_EVENT(文本 SQL 事件)

用於:

  • 事務開始 BEGIN
  • STATEMENT 格式下的 DML(INSERT/UPDATE/DELETE)
  • ROW 格式下的 DDL(CREATE/ALTER/DROP)

包含:thread_id、exec_time、error_code、status_vars(SET TIMESTAMP、SQL_MODE 等上下文)、schema、原生 SQL 文本。

# at 195
#160817 4:53:06 server id 1 end_log_pos 298 CRC32 0xf9049380
Query thread_id=3 exec_time=0 error_code=0
SET TIMESTAMP=1471380786/*!*/;
insert into test.t1 values(1,'a') /*!*/;

3. ROWS_EVENT(ROW 格式 DML 事件)

三種類型:WRITE_ROWS_EVENT、UPDATE_ROWS_EVENT、DELETE_ROWS_EVENT。不記錄 SQL 文本,而是記錄行映像:

  • INSERT:新行所有欄位值
  • UPDATE:舊值 + 新值
  • DELETE:主鍵(無主鍵則全欄位)

需搭配 TABLE_MAP_EVENT 解析表結構。查看時需加 -vv --base64-output=decode-rows。

mysql> SHOW BINLOG EVENTS IN 'mysql-bin.000027';
+------------------+-----+-------------+-----------+-------------+---------------------------------------+
| Log_name         | Pos | Event_type  | Server_id | End_log_pos | Info                                |
+------------------+-----+-------------+-----------+-------------+---------------------------------------+
| mysql-bin.000027 | 188 | Table_map   | 1         | 236         | table_id: 80 (test.t1)                |
| mysql-bin.000027 | 236 | Write_rows  | 1         | 278         | table_id: 80 flags: STMT_END_F        |
| mysql-bin.000027 | 425 | Update_rows | 1         | 475         | table_id: 80 flags: STMT_END_F        |
| mysql-bin.000027 | 622 | Delete_rows | 1         | 664         | table_id: 80 flags: STMT_END_F        |
+------------------+-----+-------------+-----------+-------------+---------------------------------------+

4. XID_EVENT(事務提交標記)

無論 STATEMENT 或 ROW 格式,事務提交時必寫入 XID_EVENT,記錄事務 ID(xid)。崩潰恢復時,InnoDB 根據 binlog 是否有 XID 決定是否提交 prepared 事務。

# at 298
#160817 4:53:06 server id 1 end_log_pos 329 CRC32 0xdb58b5b4
Xid = 25 COMMIT/*!*/;

5. ROTATE_EVENT(binlog 切換)

檔案達到 max_binlog_size 或執行 FLUSH LOGS 觸發。記錄下一個 binlog 檔名與起始位置(固定為 4)。

# at 120
#160817 12:34:26 server id 1 end_log_pos 167 CRC32 0xd965567c
Rotate to mysql-bin.000029 pos: 4

6. GTID 相關事件(GTID 模式必備)

  • GTID_LOG_EVENT:每個事務前寫入,格式 SET @@SESSION.GTID_NEXT= 'uuid:seq'。
  • PREVIOUS_GTIDS_LOG_EVENT:binlog 檔案開頭(緊跟 FORMAT_DESCRIPTION_EVENT),記錄該檔案之前所有已執行 GTID 集合。新檔案的 Previous_GTIDs = 前一檔案 Previous_GTIDs + 前一檔案所有 GTID_LOG_EVENT。
# mysql-bin.000033
# at 120 Previous_GTIDs: uuid:1
# at 191 GTID: uuid:2
# at 448 GTID: uuid:3
# mysql-bin.000034
# at 120 Previous_GTIDs: uuid:1-3

7. STOP_EVENT(正常關閉標記)

MySQL 正常關閉時寫入,表示 binlog 完整結束。崩潰時無此事件。

三、事務寫入 Binlog 時機

MySQL 使用 binlog_cache_mngr 緩存事務內所有事件,COMMIT 時一次性刷入 binlog;ROLLBACK 時直接丟棄緩存。非事務引擎(MyISAM)操作立即寫入 binlog,即使後續 ROLLBACK,已寫入的 binlog 不會回滾,需注意主從一致性風險。

四、關鍵 Binlog 參數

參數說明
max_binlog_size單檔最大值(預設 1G),達到時 rotate。事務不拆分跨檔,實際檔案可能略大。
sql_log_bin會話級開關,SET sql_log_bin=0 禁用當前會話 binlog 記錄。
sync_binlog控制 fsync 頻率。0 交給 OS(效能最好,風險最高);1 每事務提交 fsync(最安全);N 每 N 個事務組 fsync。5.7.7+ 預設 1。

總結:Binlog 事件類型是 MySQL 複製、恢復、審計的基石。熟悉 QUERY_EVENT、ROWS_EVENT、XID_EVENT、GTID_LOG_EVENT、ROTATE_EVENT 等核心類型,配合 mysqlbinlog -vv 與 SHOW BINLOG EVENTS,可精準定位資料變更、排查同步延遲、實施時間點恢復。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved