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

MySQL 複制原理深度解析:三線程架構、Statement/Row/Mixed 三種模式優劣與主流拓撲實戰

     編輯:MySQL 綜合教學

複制核心原理:三線程非同步架構

MySQL 複制為非同步,涉及三個線程協作:

線程位置職責
Binlog Dump 線程 Master 讀取 Master Binlog,發送給 Slave I/O 線程
I/O 線程 Slave 連接 Master,請求 Binlog,寫入本地 Relay Log
SQL 線程 Slave 讀取 Relay Log,解析並重放執行

關鍵流程:

  1. Slave I/O 線程連接 Master,請求指定 Binlog 位置之後的事件。
  2. Master Binlog Dump 線程讀取並發送事件(含 Binlog 檔名與位置)。
  3. Slave I/O 線程寫入 Relay Log,更新 master.info 記錄下次請求位置。
  4. Slave SQL 線程檢測到 Relay Log 新增內容,解析並順序執行。

演進歷程:早期版本單線程處理 I/O + SQL,存在效能瓶頸與資料遺失風險;Yahoo! 工程師 Jeremy Zawodny 提出雙線程分離方案,大幅降低延遲與風險。

複制實現級別:三大模式深度對比

1. Statement-Based Replication (SBR) — 基於語句

原理:記錄修改資料的 SQL 語句本身,Slave 重新執行。

優點缺點
Binlog 體積小,IO 開銷低 非確定性函數(NOW()、UUID()、RAND())導致主從不一致
易閱讀、審計、手工回放 LAST_INSERT_ID()、存儲過程、觸發器在特定情境下復制錯誤
不記錄逐行變更,ALTER TABLE 效能佳 需記錄完整上下文資訊(使用者變數、暫存表、自增值等)

2. Row-Based Replication (RBR) — 基於行

原理:記錄每行資料的實際變更(前後映像),Slave 套用行級變更。

優點缺點
完全確定性,避免函數/觸發器問題 大量更新(如無 WHERE 的 UPDATE、ALTER TABLE)產生海量 Binlog
Binlog 內容清晰,易於解析、稽核 跨資料庫/跨表的複雜關聯更新難以優化
不依賴上下文,Slave 重放更安全 無法直接從 Binlog 看出原始 SQL 語句

3. Mixed-Based Replication (MBR) — 混合模式(MySQL 5.1.8+)

原理:預設使用 SBR,遇到不安全語句自動切換 RBR。現代 MySQL(5.7/8.0)預設即為 MIXED。

  • DDL(CREATE/ALTER/DROP)→ SBR
  • 非確定性函數、UDF、存儲過程 → RBR
  • 一般 DML → SBR

主流複制拓撲架構

一主多從(最常見,90%+ 場景)

  • Master 承擔寫入,多 Slave 分擔讀取壓力。
  • 架構簡單,Master 不感知 Slave 數量,新增 Slave 無需變更 Master。
  • 適用:讀多寫少、資料即時性要求不極高(秒級延遲可接受)。

雙主互備

  • A ↔ B 雙向複制,各自為對方 Master/Slave。
  • 風險:非同步特性導致雙寫衝突(如時間點 1 A 改 10,時間點 2 B 改 20,複制延遲下可能覆蓋)。
  • 生產建議:單寫入點(VIP 漂移),或設定 auto_increment_offset/increment 避免主鍵衝突,嚴禁雙向同步寫入。

多級同步(鏈式/樹狀)

  • A → B → C,中間節點需開啟 log-slave-updates。
  • 降低 Master 直接連線壓力,但增加延遲層級。

關鍵監控指標與故障處理

  • Seconds_Behind_Master:延遲秒數,持續 > 0 需排查。
  • Slave_IO_Running / Slave_SQL_Running:任一為 No 即異常。
  • Last_IO_Error / Last_SQL_Error:具體錯誤訊息。
  • Relay_Log_Space:Relay Log 佔用空間,防止磁碟滿。

常見錯誤處理:

  • SQL 線程錯誤:STOP SLAVE SQL_THREAD → 修正資料/跳過錯誤(SET GLOBAL sql_slave_skip_counter=1) → START SLAVE SQL_THREAD。
  • IO 線程錯誤:檢查網路、防火牆、Master Binlog 是否存在、MASTER_LOG_FILE/MASTER_LOG_POS 是否正確。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved