首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫

MySQL 多線程復制遇到 Error 1872 錯誤的完整解決方案

     編輯:MySQL 資料庫相關知識

上週在生產環境遭遇一個棘手問題,經排查後發現是 MySQL 多線程復制(MTS)機制導致的 Error 1872 錯誤,特此記錄分享給各位 DBA 同仁參考。

問題背景

因 IDC 機房突發斷電(疑似挖掘機誤切光纜),導致所有伺服器重啟,其中 MySQL 5.7.10 從庫復制中斷,報錯如下:

Slave SQL for channel "": Slave failed to initialize relay log info structure from the repository, Error_code: 1872

核心原因分析

雖然採用了標準 Crash-safe 配置(relay_log_info_repository=TABLE、master_info_repository=TABLE、sync_relay_log=1、sync_relay_log_info=1),但在多線程復制(MTS)場景下,仍存在兩大固有問題:

1. Gap 事務(間隙事務)

MTS 下,後執行的事務可能先回放提交。如圖所示,事務 tx2、tx4 已提交,但 tx1、tx3 尚未提交,形成「空洞」。基於 logical_clock 的 MTS 可透過設定 slave_preserve_commit_order=1 保證提交順序,但這並不能完全解決位置追蹤問題。

MTS Gap 事務示意圖

2. Exec_Master_Log_Pos 不準確

Crash 發生時,master_info 記錄的是最早未提交事務(如 tx1)的起始位置,而非實際已提交的最新位置。這被稱為 gap-free low-watermark。關鍵在於:MTS 下 slave_relay_log_info 表的更新非事務性,導致位置資訊與實際回放進度脫節。

MySQL 內建恢復機制

MySQL 5.6 引入 slave_worker_info 表,記錄每個 Worker 線程的回放位置,且該表更新是事務性的。恢復時,MySQL 會對比 Exec_Master_Log_Pos 與各 Worker 的 Master_log_pos,判斷是否需重放事務。

版本差異與解決方案

MySQL 5.7.13 之前(含 5.7.10)

Crash 後必須手動執行以下指令修復 Gap,直接執行 CHANGE MASTER TO 會觸發 1872 錯誤:

START SLAVE UNTIL SQL_AFTER_MTS_GAPS;
START SLAVE SQL_THREAD;

MySQL 5.7.13 及以後

MySQL 內建自動修復機制,Crash 後能自動準確恢復復制狀態,無需人工干預。

本案例總結

生產環境為 MySQL 5.7.10,DBA 嘗試用 CHANGE MASTER TO 修復,導致 1872 錯誤。正確做法應先執行 START SLAVE UNTIL SQL_AFTER_MTS_GAPS 清理 Gap,再啟動 SQL 線程。後續升級至 5.7.15 過程中又遇新坑,留待下回分享。

核心提醒:MTS 環境下 Crash 後,切勿直接 CHANGE MASTER TO,務必先處理 Gap 事務。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved