分布式存儲系列:MySQL 雙向同步復制架構設計要點與制約 (v2)
本文為該系列最終篇,系統梳理雙主雙寫雙向同步復制的核心制約、原生方案分析、自定義標記 SQL 解耦實現及工程落地總結。
一、核心問題與制約
- 數據一致性衝突:同庫/表/記錄/字段兩地並發寫入,復制層無法裁決,需業務層規避 (分片/路由/樂觀鎖/最後寫入勝)。
- 主鍵衝突:自增主鍵極易重複,必須採用 UUID、雪花算法、預分段自增等全局唯一主鍵方案。
- 循環復制:復制程序寫入產生 binlog,若不識別過濾,導致 A→B→A 無限循環。
二、原生 Dual Master 方案分析
- MySQL 通過
server-id 標識 binlog 來源,配合 --log-slave-update=OFF 禁止 slave 重寫 binlog,從源頭阻斷循環。
- 優點:原生支持,無外部依賴。
缺點:強耦合 MySQL 配置,大規模部署易因配置錯誤導致事故;未解決主鍵/數據衝突。
三、自定義標記 SQL 方案 (解耦實現)
設計思路
- 復制程序寫入事務時,在事務開始後與提交前插入特定標記 SQL (更新專用標記表)。
- 標記 SQL 進入 binlog,復制程序讀取 binlog 時識別標記,判定該事務為復制產生,過濾丟棄,實現回環控制。
Binlog 事務結構與讀取邊界分析
- 綠色區:業務正常事務。
- 紅色區:復制程序寫入事務 (含藍色標記 SQL)。
批量讀取 binlog 時存在 5 種邊界情況,唯有第 5 種 (讀取範圍完全落在紅色區中段,缺少首尾標記) 會導致無法識別而循環同步。
解決方案:固定讀取窗口 ≥ 最大事務長度
強制復制程序每次批量讀取的 binlog 位置範圍長度 不小於寫入端單個事務的最大 binlog 長度。確保每次讀取要么完整包含一個事務 (含首尾標記),要么完全不包含復制事務,從根本上消除第 5 種情況。
四、總結與最佳實踐建議
- 雙向同步復制的工程關鍵在於 標記識別 與 讀取窗口控制。
- 同庫同表同記錄同字段的雙寫衝突,復制層無法仲裁:
① 首選業務架構規避 (分庫分表/路由隔離);
② 次選 LWW (最後寫入勝) + 時鐘同步 (NTP/PTP);
③ 避免在復制層嘗試解決業務語義衝突。
- 生產環境建議:
— 主鍵使用雪花算法/UUID。
— 部署 ProxySQL/HAProxy 做讀寫分離與故障切換,而非直接雙主雙寫。
— 關鍵業務採用單主多從 + 異步/半同步復制,簡單可靠。