主從復制中斷或數據不一致是 DBA 高頻痛點。本文將故障分為「IO 線程斷連」「SQL 線程報錯」「數據不一致」三級,提供標準化排查修復 SOP。
# 1. 查看錯誤日志 (首選)
tail -f /var/log/mysqld.log
# 2. 關鍵信號
# IO 線程連接成功:
# 140304 11:59:18 [Note] Slave I/O thread: connected to master 'repl@192.168.1.1:3306', replication started in log 'binlog.000011' at position 294
# SQL 線程初始化:
# 140304 11:59:08 [Note] Slave SQL thread initialized, starting replication in log 'binlog.000011' at position 294, relay log 'mysql-relay-bin.000001' position: 4
典型錯誤:連接超時、認證失敗、網絡不通、主庫 Binlog 被清理 (位點不存在)。
telnet master_ip 3306、ping master_ip。/etc/my.cnf、/var/lib/mysql/master.info 中的 host/user/password。SHOW BINARY LOGS 是否包含 master.info 記錄的文件。STOP SLAVE;
CHANGE MASTER TO
MASTER_HOST='192.168.1.1',
MASTER_USER='repl',
MASTER_PASSWORD='pass',
MASTER_LOG_FILE='binlog.000011', -- 主庫現有最早 Binlog
MASTER_LOG_POS=4; -- 從頭開始
START SLAVE;
典型錯誤:主鍵衝突 (1062)、外鍵失敗、表不存在、列不匹配、死鎖超時。
SHOW SLAVE STATUS\G 記下 Last_SQL_Error、Exec_Master_Log_Pos。SET GLOBAL sql_slave_skip_counter=1; START SLAVE; (跳過 1 事務) 或手動刪除衝突行後重試。START SLAVE 重試即可。檢測手段:pt-table-checksum (Percona Toolkit) 定期巡檢,或業務發現異常。
FLUSH TABLES WITH READ LOCK) 確保數據靜止。mysqldump --single-transaction --master-data=2 --routines --databases db1 > full.sql
# 記錄輸出的 CHANGE MASTER TO 位點
mysql -uroot -p < full.sql
STOP SLAVE;
CHANGE MASTER TO MASTER_LOG_FILE='binlog.xxx', MASTER_LOG_POS=yyy;
START SLAVE;
pt-table-checksum 再次巡檢,確認無差異。gtid_mode=ON, enforce_gtid_consistency=ON,自動定位位點,極大簡化修復。binlog_format=ROW,避免 SBR 非確定性導致邏輯不一致。rpl_semi_sync_master=ON,主庫至少一從庫收到事務才提交,減少數據丟失窗口。pt-table-checksum + pt-table-sync 修復。Seconds_Behind_Master > 300、Slave_IO_Running != Yes、Slave_SQL_Running != Yes 立即告警。#!/bin/bash
# fix_replication.sh
MASTER_HOST=$1
MASTER_USER=$2
MASTER_PASS=$3
MASTER_LOG_FILE=$4
MASTER_LOG_POS=$5
mysql -uroot -p$ROOT_PASS -e "STOP SLAVE;"
mysql -uroot -p$ROOT_PASS -e "CHANGE MASTER TO MASTER_HOST='$MASTER_HOST', MASTER_USER='$MASTER_USER', MASTER_PASSWORD='$MASTER_PASS', MASTER_LOG_FILE='$MASTER_LOG_FILE', MASTER_LOG_POS=$MASTER_LOG_POS;"
mysql -uroot -p$ROOT_PASS -e "START SLAVE;"
sleep 3
mysql -uroot -p$ROOT_PASS -e "SHOW SLAVE STATUS\G" | grep -E 'Slave_IO_Running|Slave_SQL_Running|Seconds_Behind_Master'