MySQL 5.6 引入全局事務 ID (GTID),不僅簡化了主從切換(無需手動找 binlog position),更引入了全新的複制協議。本文對比新舊協議核心差異,詳細講解 sql_slave_skip_counter 失效原因、GTID 下跳過事務正確姿勢、錯誤事務導致的故障轉移風險與規避方案。
| 維度 | 舊協議 | 新協議 (GTID) |
|---|---|---|
| 從庫請求 | CHANGE MASTER TO MASTER_LOG_FILE='binlog.000001', MASTER_LOG_POS=123 | 發送已執行 GTID 集合:GTID_SET = 'uuid:1-100' |
| 主庫響應 | 從指定位置順序發送所有事務 | 計算差集,僅發送從庫缺失的事務 |
| 幂等性 | 無(重複執行風險) | 嚴格保證 每個 GTID 在從庫僅執行一次 |
假設從庫缺失事務 2,但請求從事務 4 開始:
這是 GTID 協議「以集合為基準、按需補全」設計的核心價值。
舊版 SET GLOBAL sql_slave_skip_counter = N 在 GTID 模式下禁止使用。原因:
1236: master has purged binary logs containing GTIDs that the slave requires → 複制中斷。SET gtid_next = 'uuid:N'; -- 要跳過的 GTID
BEGIN; COMMIT; -- 空事務
SET gtid_next = 'AUTOMATIC';
從庫記錄「已執行該 GTID」,主庫比對集合時視為已同步,不再發送原事務。
場景:從庫 S1 曾本地執行 CREATE DATABASE mydb;(未寫 binlog 或已 Purge),主庫 M 執行 CREATE DATABASE IF NOT EXISTS mydb;。
CREATE DATABASE mydb;。1007: Can't create database 'mydb'; database exists → 複制中斷。FLUSH LOGS; PURGE BINARY LOGS TO ... 導致該 GTID 不在 binlog。1236 → 永久中斷。SET GLOBAL super_read_only=ON;(5.7.8+),防止誤寫入。SET SESSION sql_log_bin=0; -- 執行 DDL/維護 -- SET SESSION sql_log_bin=1;Seconds_Behind_Master、Slave_SQL_Running_State、gtid_executed 與主庫差集。GTID 新協議通過「集合比對 + 缺失補全」實現了自動收斂一致,但也帶來了新約束:嚴禁從庫獨立寫入、跳過事務需注入空事務、Purge 需謹慎評估從庫 GTID 需求。理解協議本質,才能在架構變更、故障轉移、版本升級中游刃有餘。