数据库主从同步故障排查实战指南
引言
数据库主从同步一旦出问题,轻则数据延迟,重则主从不一致,影响业务。
很多人遇到报错就手忙脚乱,其实只要按步骤排查,大部分问题都能自己解决。
本文从零开始,带你走一遍数据库主从同步故障排查的完整流程,所有命令和操作路径都写清楚,跟着做就行。
第一步:确认主从同步状态与基础环境
排查之前,先搞清楚当前同步到底卡在哪。
登录从库服务器,执行以下命令查看同步线程状态:
SHOW SLAVE STATUS\G
重点关注三个字段:
Slave_IO_Running:IO线程是否运行。如果显示Yes表示正常,Connecting表示连接不上主库,No表示已停止。Slave_SQL_Running:SQL线程是否运行。Yes正常,No表示执行中继日志时出错。Seconds_Behind_Master:从库落后主库的秒数。数字越大说明延迟越严重,NULL表示同步未正常建立。
另外,检查从库是否能访问主库的IP和端口:
mysql -h 主库IP -P 3306 -u 同步用户 -p -e "SELECT 1;"
如果连接失败,检查防火墙(宝塔面板 -> 安全 -> 防火墙,确保3306端口放行)、主库的 bind-address 配置以及用户权限。
核心排查步骤:IO线程和SQL线程常见报错
1. IO线程报错:Slave_IO_Running: Connecting 或 No
最常见的原因是主库连接信息错误或主库变更了binlog位置。
先确认主从复制配置:
SHOW SLAVE STATUS\G
查看 Master_Host、Master_User、Master_Port、Master_Log_File、Read_Master_Log_Pos 是否正确。
如果主库发生过重新搭建或binlog清理,需要重新设置同步点。
解决方法:记下主库当前的binlog文件名和位置(在主库执行 SHOW MASTER STATUS;),然后回到从库执行:
STOP SLAVE;
CHANGE MASTER TO MASTER_LOG_FILE='mysql-bin.000001', MASTER_LOG_POS=123456;
START SLAVE;
2. SQL线程报错:Slave_SQL_Running: No
SQL线程报错意味着从库在应用主库的变更时遇到冲突,比如主键重复、表不存在或数据类型不匹配。
查看具体错误:
SHOW SLAVE STATUS\G
找到 Last_Error 字段,里面会说明出错的原因和位置。
例如:
Error 'Duplicate entry '1001' for key 'PRIMARY'' on query ...
如果错误不严重(比如少数数据冲突),可以跳过当前事务继续同步:
STOP SLAVE;
SET GLOBAL SQL_SLAVE_SKIP_COUNTER = 1;
START SLAVE;
然后再检查状态。
如果频繁出现跳过,说明主从数据不一致,建议重新搭建从库或使用 pt-table-sync 修复数据。
3. 延迟过大:Seconds_Behind_Master 持续增长
延迟可能由大事务、从库硬件性能差、网络带宽不足引起。
优先检查从库的磁盘IO和CPU使用率(top、iostat),以及主库是否执行了长时间未提交的事务。
从库可以开启并行复制(MySQL 5.7+):
slave_parallel_workers = 4
slave_parallel_type = LOGICAL_CLOCK
修改my.cnf后重启从库线程:
STOP SLAVE;
START SLAVE;
避坑提醒:这些细节最容易导致故障
- 主库binlog过期:默认binlog过期天数较短(如7天),如果从库断连超过这个时间,重连时会找不到binlog,必须重新搭建从库。建议设置
expire_logs_days = 15或更大。 - 大事务:一次性更新几百万行数据,会导致从库长时间落后,甚至超时。尽量拆分大事务,或者使用行级复制。
- 网络抖动:从库IO线程会不断重连,但频繁连接错误可能导致
max_connect_errors超过限制,主库会拒绝连接。可以在主库执行FLUSH HOSTS;或调大max_connect_errors。 - 配置不一致:主从的
sql_mode、字符集、时区等必须一致,否则容易报错。对比两边的SHOW VARIABLES LIKE 'sql_mode';和SHOW VARIABLES LIKE 'character_set%';。
验证恢复效果
修复后,重新执行:
SHOW SLAVE STATUS\G
确认 Slave_IO_Running 和 Slave_SQL_Running 都为 Yes,并且 Seconds_Behind_Master 逐渐变小直到0。
也可以在主库插入一条测试数据,等几秒后在从库查询,看能否查到。
例如在主库执行:
INSERT INTO test.health_check(id) VALUES(1);
回到从库:
SELECT * FROM test.health_check;
如果能查到相同数据,说明同步恢复正常。
结语
数据库主从同步故障排查并不神秘,按照状态确认、IO线程检查、SQL线程纠错、避坑检查、效果验证这条线走,大部分问题都能解决。
如果你正在处理类似问题,建议先按本文步骤完整执行一遍,再根据实际环境微调。
遇到异常时,优先回看避坑和高频问题部分,往往能快速定位。