数据库主从同步故障排查修复方案:数据库主从同步故障排查与修复
故障现象与排查前的准备工作
先确定主从同步是否真的出现问题。
常见表现有:从库数据更新延迟、应用连接报错“Slave has more rows than master”或“Could not execute Write_rows event”。
排错前需要准备三样东西:root权限的从库账号(有 REPLICATION SLAVE 和 REPLICATION CLIENT 权限)、主库的 binlog 和 position 信息(存好 SHOW MASTER STATUS 的结果)、以及从库的 MySQL 配置文件路径(通常为 /etc/my.cnf 或 /etc/mysql/mysql.conf.d/mysqld.cnf)。
如果是从库刚搭建就报错,很可能 binlog 位置设错;
如果是运行一段时间突然中断,优先检查网络和磁盘空间。
查看同步状态与识别错误类型
登录从库,执行以下命令,重点关注 Slave_IO_Running 和 Slave_SQL_Running 字段:
SHOW SLAVE STATUS\G
输出会很长,你需要提取这几项:
Slave_IO_Running: Yes/No— IO 线程是否正常连接主库拉取 binlog。Slave_SQL_Running: Yes/No— SQL 线程是否正常重放 binlog。Last_IO_Errno和Last_IO_Error— IO 线程报错编号与原因。Last_SQL_Errno和Last_SQL_Error— SQL 线程报错编号与原因。Seconds_Behind_Master— 延迟秒数(非精确,但能反映趋势)。
常见错误类型:
- IO 线程报 1236:master 端 binlog 被清理或位置无效。
- SQL 线程报 1062:主键冲突(从库已有相同主键记录)。
- SQL 线程报 1032:更新/删除时找不到匹配行(数据不一致)。
修复方案:从简单跳过到重建从库
方案一:跳过指定数量的错误(临时救急)
如果错误能接受跳过(例如主键冲突且影响不大),执行:
STOP SLAVE;
SET GLOBAL sql_slave_skip_counter = 1; -- 跳过一个事务
START SLAVE;
SHOW SLAVE STATUS\G
重复查看是否还有新错误,若同一类错误成百上千,建议放弃跳过,改用方案二。
方案二:重建从库(干净彻底)
- 在主库上锁表并记录 binlog 位置:
FLUSH TABLES WITH READ LOCK;
SHOW MASTER STATUS; -- 记下 File 和 Position
另开一个终端用 mysqldump 导出数据(保留 --master-data=2):
mysqldump -u root -p --all-databases --master-data=2 > /tmp/master_dump.sql
导完后在主库解锁:
UNLOCK TABLES;
- 把 dump 文件传到从库,从库上先停止同步并重置:
STOP SLAVE;
RESET SLAVE ALL;
- 导入数据:
mysql -u root -p < /tmp/master_dump.sql
- 重新设置同步(从 dump 文件头部找到
CHANGE MASTER TO语句,或手动填写):
CHANGE MASTER TO
MASTER_HOST='主库IP',
MASTER_USER='repl',
MASTER_PASSWORD='密码',
MASTER_LOG_FILE='mysql-bin.000001', -- 用你记录的 File
MASTER_LOG_POS=123456789; -- 用你记录的 Position
START SLAVE;
避坑说明:权限、网络与数据一致性
- 权限不够:从库连接主库的用户必须拥有
REPLICATION SLAVE和REPLICATION CLIENT。检查方法:在主库执行SHOW GRANTS FOR 'repl'@'%';。 - 主库 binlog 过期:如果主库设置了
expire_logs_days较小,历史上的 binlog 可能已被删除,导致从库 IO 线程 1236 错误。临时措施是调大expire_logs_days并重启主库,或者直接从备份重建。 - 防火墙或安全组:务必确保从库能访问主库的 3306 端口(或其他自定义端口)。测试:
telnet 主库IP 3306。 - 数据一致性:跳过错误或单独修复某张表可能导致更深的差异。如果业务允许,优先选择重建从库,而不是逐个跳过。
- 大事务:一个大的
ALTER TABLE或DELETE可能导致从库延迟激增甚至断开。建议在主库低峰期执行大操作,并监控Seconds_Behind_Master。
验证同步与持续监控
重建或修复后,执行以下命令确认状态:
SHOW SLAVE STATUS\G
关键检查点:
Slave_IO_Running: YesSlave_SQL_Running: YesSeconds_Behind_Master: 0(或很小且在下降)
在主库插入一条测试数据:
INSERT INTO test.sync_check(id, val) VALUES(1, 'ok');
等待几秒后到从库查询该表,若能查到则同步完全恢复。
建议配置监控告警,例如使用脚本定期检查 Seconds_Behind_Master 是否超过阈值,或 Slave_IO_Running 是否为 No。
常见的开源监控工具如 Prometheus + mysqld_exporter 可以直接采集这些指标。
如果你刚遇到主从同步中断,先按本文第一步查看报错原因,再根据错误类型选择方案一或方案二。
记住:永远不要在生产库上直接操作未验证的修复语句,先备份当前从库数据再动手。