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

MySQL 主從數據不一致?三種恢復策略與跳過錯誤事務實戰指南

     編輯:MySQL 資料庫相關知識

現象:從庫復制中斷,報主鍵衝突

mysql> SHOW SLAVE STATUS\G
...
Last_SQL_Error: Could not execute Write_rows event on table xxx; 
Duplicate entry '123' for key 'PRIMARY'
Slave_SQL_Running: No

三種恢復策略選型

策略適用場景優點缺點
1. 重新搭建從庫數據量小、容忍停機、要求絕對一致徹底乾淨耗時長、需鎖主庫/停寫入
2. 從備份恢復 + Binlog 重放數據量大、有冷備份、Binlog 全量不鎖主庫、可控操作步驟多、需精確時間點
3. 跳過錯誤事務 (SQL_SLAVE_SKIP_COUNTER)錯誤明確、數據影響可控、需快速恢復最快、無停機**可能導致數據不一致**

策略 3 實戰:跳過錯誤事務標準流程

步驟 1:停止 SQL 線程

STOP SLAVE SQL_THREAD;

步驟 2:設置跳過計數器(每次跳 1 個事務)

SET GLOBAL SQL_SLAVE_SKIP_COUNTER = 1;

步驟 3:啟動 SQL 線程並觀察

START SLAVE SQL_THREAD;
SHOW SLAVE STATUS\G  -- 確認 Slave_SQL_Running: Yes

步驟 4:如仍報錯,重複 1-3 直到恢復

建議: 先用 SHOW BINLOG EVENTS 分析主庫 Binlog 確認錯誤事務數量,再批量設置計數器。

進階:Binlog 事件分析定位錯誤事務

從庫獲取復制坐標

SHOW SLAVE STATUS\G
-- 關鍵字段:
Master_Log_File: mysql-bin.000217
Read_Master_Log_Pos: 673146776

主庫查看該位置後的事務

SHOW BINLOG EVENTS IN 'mysql-bin.000217' FROM 673146776\G
-- 或命令行
mysqlbinlog mysql-bin.000217 --start-position=673146776

判斷需跳過事務數,一次性設置

SET GLOBAL SQL_SLAVE_SKIP_COUNTER = N;  -- N 為需跳過事務數
START SLAVE SQL_THREAD;

恢復後性能抖動應對:Sending data 長耗時分析

跳過事務啟動後,Seconds_Behind_Master 緩慢下降,SHOW PROCESSLIST 顯示復制 SQL 線程狀態 Sending data 耗時極長。

開啟 Profiling 定位

SET profiling=1;
-- 等待該長查詢結束
SHOW PROFILES;
SHOW PROFILE FOR QUERY ;

同樣定位到大字段/溢出頁/無索引掃描等問題,**從庫同步執行同樣受主庫慢查詢影響**。

避坑經驗:STOP SLAVE 卡住怎麼辦?

  • 現象:STOP SLAVE 執行不返回,疑被長查詢/鎖阻塞
  • 應對:不要反覆執行 SLAVE 命令,等待阻塞線程結束,**或直接重啟 MySQL**(快止血)

啟動報錯:ERROR 1872 (HY000): Slave failed to initialize relay log info structure

  • 現象:重啟後 START SLAVE 報此錯
  • 嘗試:重新配置主從(太重)
  • 意外發現:mysqld_safe --user=mysql 啟動正常,mysqld 直接啟動報錯
  • 推測:權限/路徑/臨時文件殘留問題,**mysqld_safe 環境更完善**

總結

  1. 優先評估策略 1/2(重搭/備份恢復),保證數據絕對一致
  2. 不得已用策略 3(跳過事務),**必須先分析 Binlog 確認影響範圍**,事後補數據
  3. 運維規範: 監控告警覆蓋 Slave_SQL_Running、Seconds_Behind_Master、Last_SQL_Error
  4. 啟動統一用 mysqld_safe,避免環境差異導致的詭異錯誤
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved