数据库主从同步中断故障排查修复方案
数据库主从同步中断全流程排查与修复指南
主从同步断开是 MySQL 运维里最常遇到的故障之一,一旦 Slave 线程停止,从库数据就会滞后甚至完全不可用。
很多新手一看到 Slave_IO_Running: No 或 Slave_SQL_Running: No 就慌了,其实按顺序排查通常都能修好。
下面直接从现象开始,一步步带你走完排查和修复过程。
准备工作:确认同步状态和错误信息
在动手修复之前,必须先搞清楚断开的具体原因。
登录从库 MySQL 终端,执行下面的命令查看同步线程状态:
SHOW SLAVE STATUS\G
重点关注几个关键字段:
- Slave_IO_Running:如果为 No,说明 IO 线程无法从主库拉取 binlog。
- Slave_SQL_Running:如果为 No,说明 SQL 线程执行中继日志时出错(例如表结构冲突、主键重复)。
- Last_IO_Error / Last_SQL_Error:直接告诉你上次失败的具体报错,这是最关键的线索。
- Seconds_Behind_Master:如果为 NULL 或持续增大,同样代表不同步。
确认错误信息后,不要急着执行 stop slave / start slave,先搞清楚错误类型再动手。
分步排查与修复操作
针对不同的状态,修复方法也不同。
这里列出最常见的 3 种场景及对应操作:
场景一:Slave_IO_Running: No(IO 线程连不上主库)
报错通常是 Error connecting to master 或 Got fatal error 1236 from master when reading data from binary log。
排查方向:
- 检查主库网络是否可达:
ping 主库IP。 - 确认主库的复制账号是否正常:
SELECT user, host FROM mysql.user WHERE user='你的复制用户';。 - 在主库上检查
SHOW MASTER STATUS;,看 File 和 Position 是否发生变化。如果 File 不存在(比如 binlog 已被 purge),需要重新同步。
修复命令示例(重新指定主库信息):
STOP SLAVE;
CHANGE MASTER TO
MASTER_HOST='主库IP',
MASTER_USER='复制用户',
MASTER_PASSWORD='密码',
MASTER_LOG_FILE='从SHOW MASTER STATUS获取的binlog文件名',
MASTER_LOG_POS=从SHOW MASTER STATUS获取的位置号;
START SLAVE;
对于 GTID 模式,可以不用指定日志文件和位置:
STOP SLAVE;
CHANGE MASTER TO MASTER_AUTO_POSITION=1;
START SLAVE;
场景二:Slave_SQL_Running: No(SQL 线程执行报错)
常见错误码 1062(主键冲突)或 1032(记录不存在)。
修复思路:
- 如果错误很少(比如只有几条数据冲突),可以手动补全或删除冲突数据,然后跳过一个事务:
STOP SLAVE;
SET GLOBAL SQL_SLAVE_SKIP_COUNTER = 1;
START SLAVE;
- 如果错误太多,或者主从数据差异很大,建议重新同步从库(全量 dump + 增量)。
场景三:两者都为 No,且 Last_IO_Error 显示 binlog 丢失
说明主库的 binlog 已被清理,从库跟不上。
必须重新做全量同步:
- 主库导出数据:
mysqldump -u root -p --all-databases --master-data=2 > full.sql。 - 把导出的 SQL 传到从库并导入:
mysql -u root -p < full.sql。 - 然后执行 CHANGE MASTER(带上导出的日志文件名和 Position,或者使用
MASTER_AUTO_POSITION=1如果是 GTID)。
避坑指南:这些操作千万别做错
- 不要直接用 reset slave:
RESET SLAVE会清空 relay log 信息和 master info,但不会改主库的 binlog 状态,容易造成重新配置后依然报错。应该先 stop slave,再 change master。 - 跳过错误要谨慎:
SQL_SLAVE_SKIP_COUNTER只能跳过单条错误,如果错误重复出现(比如表结构不一致),跳过了也没用,必须修复表或重新同步。 - 检查主库 binlog 保留时间:通过
SHOW VARIABLES LIKE 'expire_logs_days';检查,建议设置不少于 7 天,避免从库临时断连后 binlog 被清理。 - 修改参数后记得重启从库 SQL 线程:改完
server_id、log_slave_updates等参数需要重启 MySQL 生效。
验证同步是否已恢复
修复后执行以下检查:
SHOW SLAVE STATUS\G
确认两个 Running 字段都为 Yes,并且 Seconds_Behind_Master 在几秒内从高值降为 0 或很小的数字。
同时可以对比主从库同一张表的数据行数:
SELECT COUNT(*) FROM 某张重要表; -- 主库执行
SELECT COUNT(*) FROM 某张重要表; -- 从库执行
数量一致说明基本没问题。
如果还有延迟,可以查看 SHOW PROCESSLIST; 确认是否有大查询阻塞。
高频问题 FAQ
Q:Seconds_Behind_Master 为 0 但数据不一致怎么办?
A:Seconds_Behind_Master 只代表从库执行中继日志的滞后时间,不代表数据绝对一致。如果表结构不一致或者出现 relay log 损坏,会有差异。建议用 pt-table-checksum 做一致性校验。
Q:执行 CHANGE MASTER 后 IO 线程还是 No,怎么办?
A:检查主库的复制账号权限是否完整(至少 REPLICATION SLAVE、REPLICATION CLIENT),同时确认防火墙没有阻断 3306 端口。
Q:主从同步中断时间很长,能不能不重新全量同步?
A:如果主库的 binlog 还没有被 purge,可以尝试指定更早的日志文件和位置(通过 SHOW BINARY LOGS; 查找)。但通常建议重新做一次全量同步,更安全可靠。
如果你正在处理主从同步中断,建议先按本文排查错误信息,再选择对应场景修复,遇到复杂错误时优先考虑重新同步。