必须先查SHOW SLAVE STATUS\G中Slave_IO_Running和Slave_SQL_Running状态:IO线程为No则排查网络、权限、主库存活;SQL线程为No则依据Last_SQL_Error(如1062、1032、1236)选择跳过、修复或重建从库;两者皆No需优先恢复IO链路;GTID模式禁用sql_slave_skip_counter,须用SET GTID_NEXT注入空事务。

先看 SHOW SLAVE STATUS\G 里哪条线程挂了
恢复方案完全取决于 Slave_IO_Running 和 Slave_SQL_Running 哪个是 No,不是所有“复制中断”都该重启或跳过。
-
Slave_IO_Running: No→ 主库连不上:查网络、防火墙、复制账号权限、主库mysqld是否存活,SHOW MASTER STATUS能否执行 -
Slave_SQL_Running: No→ 中继日志执行失败:重点看Last_SQL_Error,比如Error_code: 1062(主键冲突)、Error_code: 1032(行不存在)、Got fatal error 1236(binlog 文件丢失) - 两个都是
No:大概率主库已不可达或从库配置被重置,优先排查 IO 链路
遇到 ERROR 1236 别硬拉,binlog 真没了就得重搭
Got fatal error 1236 意味着从库要拉的 binlog 文件(如 mysql-bin.000042)在主库上已被 purge,SET GLOBAL sql_slave_skip_counter = 1 完全无效——跳过没用,因为根本收不到日志。
- 确认主库 binlog 是否还在:
SHOW BINARY LOGS;对比从库Master_Log_File字段 - 若缺失,必须重建从库:主库做
mysqldump --master-data=2 --single-transaction或xtrabackup全量备份 - 导入后,用备份文件里自带的
CHANGE MASTER TO语句重配,不要手输MASTER_LOG_POS - GTID 模式下,还要同步
gtid_purged:主库查SELECT @@global.gtid_executed;,从库SET GLOBAL gtid_purged = '...';
SQL 线程报错时,跳过前先判断错误是否可逆
sql_slave_skip_counter 是把双刃剑。它只跳过当前事件,不修复数据差异,更不保证后续语句能顺利执行。
- 适合跳过的场景:单次临时表创建失败、某条 INSERT 因唯一索引重复(且业务允许丢弃该记录)
- 不能跳过的场景:反复出现的
1062或1032错误、DDL 导致表结构不一致、从库被手动写入过数据 - GTID 模式下禁用
sql_slave_skip_counter:改用SET GTID_NEXT='xxx'; BEGIN; COMMIT;注入空事务,或重置gtid_purged - 跳过后必须验证:
Seconds_Behind_Master是否持续下降?抽样比对关键表COUNT(*)和MD5(GROUP_CONCAT(...))
容器环境里,别忽略网络和权限的隐性约束
Docker 或 Kubernetes 下,SHOW SLAVE STATUS 显示异常,90% 不是 MySQL 本身问题,而是基础设施层卡住了。
- 检查容器间连通性:
docker exec -it mysql-slave nc -zv mysql-master 3306,注意服务名是否在同一个自定义 network 中 - 确认主库复制账号授权范围:
SHOW GRANTS FOR 'repl'@'%';,K8s 中常因 DNS 解析或 headless service 导致'repl'@'%'不生效,需显式授权'repl'@'10.244.1.5'类似地址 - 从库容器启动时未等主库就绪,导致首次
START SLAVE失败:加健康检查或 initContainer 等待主库mysqladmin ping成功 - 日志路径挂载权限问题:中继日志写不进
/var/lib/mysql,Last_IO_Error可能报 “Permission denied” 而非连接失败
真正麻烦的不是怎么恢复,而是恢复后没人核对数据一致性。延迟归零不代表数据对得上,pt-table-checksum 或至少三张核心表的手动校验,漏掉这步,等于给线上埋了个定时炸弹。


















