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

MySQL 主從同步故障速查手冊:Slave_IO/SQL_Running 為 No 的雙軌修復方案

     編輯:MySQL 資料庫相關知識

故障現象速識

現象典型錯誤碼核心原因
Slave_IO_Running: No1236, 1045, 2003網絡不通、認證失敗、Binlog 位點無效、主庫 Binlog 已清理
Slave_SQL_Running: No1062, 1032, 1053主鍵衝突(1062)、行不存在(1032)、主庫語句執行錯誤(1053)

通用診斷步驟

  1. SHOW SLAVE STATUS\G 記錄 Last_IO_Error / Last_SQL_Error、Master_Log_File、Read_Master_Log_Pos
  2. SHOW MASTER STATUS 對比主庫當前 Binlog 文件/位點
  3. 檢查錯誤日志 tail -f /var/log/mysqld.log(或 Windows 事件查看器)
  4. 驗證網絡連通性:telnet master_ip 3306

軌道一:Slave_IO_Running: No 修復

場景 A:Binlog 位點無效(主庫重啟/清理導致)

錯誤日志:Client requested master to start replication from impossible position (errno=1236)

修復步驟

-- 1. 停止 Slave
STOP SLAVE;

-- 2. 獲取主庫最新 Binlog 位點
SHOW MASTER STATUS;
-- 假設返回: mysql-bin.000080, 0

-- 3. 重新指向(從新文件開頭開始)
CHANGE MASTER TO
MASTER_HOST='master_ip',
MASTER_USER='repl_user',
MASTER_PASSWORD='password',
MASTER_LOG_FILE='mysql-bin.000080',
MASTER_LOG_POS=0;

-- 4. 啟動
START SLAVE;

注意:若中間有數據未同步,將導致數據不一致。生產環境需結合備份恢復。

場景 B:網絡/認證問題

  • 檢查防火牆/安全組:Master 3306 對 Slave IP 放行
  • 驗證賬號:SELECT User, Host FROM mysql.user WHERE User='repl_user';
  • 測試連接:mysql -h master_ip -u repl_user -p

場景 C:主庫 Binlog 已過期清理

對策:
1. 從備份恢復 Slave 全量數據
2. 記錄備份時刻對應的 Master Binlog 位點
3. 按場景 A 步驟重新建立同步

軌道二:Slave_SQL_Running: No 修復

場景 A:主鍵衝突 (Errno 1062)

原因:Slave 端有獨立寫入、或並行復制衝突。

方案一:跳過單個錯誤事件(最常用)

STOP SLAVE;
SET GLOBAL SQL_SLAVE_SKIP_COUNTER = 1;
START SLAVE;

原理:跳過當前報錯的事件(一條 SQL 或一個事務),繼續執行後續事件。

方案二:手動修正數據後跳過

  1. SHOW SLAVE STATUS\G 獲取報錯 SQL(Last_SQL_Error)
  2. 在 Slave 手動執行修正(如刪除衝突行、調整自增值)
  3. 執行方案一跳過

場景 B:行不存在 (Errno 1032)

原因:UPDATE/DELETE 目標行在 Slave 不存在。

修復

-- 手動補齊缺失行(從 Master 查詢對應數據)
INSERT INTO tbl (...) VALUES (...);  -- 或 UPDATE 修正
-- 然後跳過
STOP SLAVE;
SET GLOBAL SQL_SLAVE_SKIP_COUNTER = 1;
START SLAVE;

場景 C:主庫語句執行錯誤 (Errno 1053)

現象:Query partially completed on the master (error on master: 1053) and was aborted.

修復

STOP SLAVE;
-- 手動在 Slave 執行報錯的那條 SQL(從 Last_SQL_Error 獲取)
INSERT INTO hx_stat_record ...;
SET GLOBAL SQL_SLAVE_SKIP_COUNTER = 1;
START SLAVE;

進階修復:GTID 模式(MySQL 5.6+)

-- 重置 GTID 執行歷史
STOP SLAVE;
RESET SLAVE ALL;
CHANGE MASTER TO MASTER_AUTO_POSITION = 1;
START SLAVE;

優勢:無需手動管理 Binlog 位點,自動定位斷點續傳。

避坑與最佳實踐

  1. 嚴禁 Slave 寫入:設置 read_only=1、super_read_only=1(5.7.8+)
  2. Binlog 保留策略:Master expire_logs_days >= 7,配合備份週期
  3. 監控三件套:Slave_IO_Running、Slave_SQL_Running、Seconds_Behind_Master 全量納入監控
  4. 定期演練:季度模擬主庫故障切換,驗證 Slave 可用性
  5. 錯誤日志保留:設置 log_error_verbosity=3 記錄完整錯誤上下文

一鍵診斷腳本

#!/bin/bash
# check_slave_status.sh
STATUS=$(mysql -e "SHOW SLAVE STATUS\G" | grep -E 'Slave_(IO|SQL)_Running|Last_.*_Error|Seconds_Behind_Master')
IO=$(echo "$STATUS" | grep Slave_IO_Running | awk '{print $2}')
SQL=$(echo "$STATUS" | grep Slave_SQL_Running | awk '{print $2}')
BEHIND=$(echo "$STATUS" | grep Seconds_Behind_Master | awk '{print $2}')

if [ "$IO" != "Yes" ] || [ "$SQL" != "Yes" ]; then
    echo "ALERT: Slave status abnormal!"
    echo "$STATUS"
    exit 1
elif [ "$BEHIND" -gt 300 ]; then
    echo "WARN: Slave lag ${BEHIND}s > 5min"
    exit 2
else
    echo "OK: Slave running normally, lag ${BEHIND}s"
fi

總結

IO 線程斷 = 連不上/找不到日志 → 檢查網絡/認證/位點重置
SQL 線程斷 = 執行出錯 → 看錯誤碼:1062/1032 跳過或修數據,1053 手執行再跳過
核心原則:先診斷再動手,跳過前必備份,修復後必驗證數據一致性。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved