主从复制线程停止是明确故障,需依last_io_error/last_sql_error定位原因:i/o停多因网络、权限、server_uuid冲突或binlog缺失;sql停常见唯一键冲突、记录缺失、死锁或表结构不一致;双空则元数据损坏需reset slave all。

主从复制线程停止不是“偶发卡顿”,而是明确的故障信号——Slave_IO_Running: No 或 Slave_SQL_Running: No 一旦出现,说明复制已中断,必须人工介入。盲目 START SLAVE 通常无效,关键在快速定位线程停在哪、为什么停。
看 Last_IO_Error 和 Last_SQL_Error 字段
这是最直接的线索,错误信息就写在 SHOW SLAVE STATUS\G 输出里,别跳过它。
-
Last_IO_Error非空,说明 I/O 线程在连接主库或拉取 binlog 时失败:常见是网络不通、主库用户权限不足、server_uuid冲突、主库 binlog 文件被 purge 或位点无效 -
Last_SQL_Error非空,说明 SQL 线程在回放 relay log 时报错:典型如ERROR 1062(唯一键冲突)、ERROR 1032(找不到记录)、ERROR 1205(死锁)、表结构不一致、语句含从库不支持的函数 - 两个字段都为空但线程为
No?极大概率是元数据文件损坏(如master.info、relay-log.info),需RESET SLAVE ALL清理后重配
确认线程卡在哪个位置
仅看运行状态不够,必须锁定具体坐标,否则无法决定是跳过、重设还是重做。
- I/O 线程卡点看
Master_Host、Master_Port是否可连,再查Master_Log_File和Read_Master_Log_Pos—— 这是从库“想读”的位置 - SQL 线程卡点看
Relay_Master_Log_File和Exec_Master_Log_Pos—— 这是“最后成功执行到”的主库 binlog 位置 - 用
mysqlbinlog --base64-output=decode-rows -v /path/to/binlog.000001 | grep -A 5 -B 5 "Exec_Master_Log_Pos值"反查原始语句,确认是否真不可重放 - GTID 模式下重点比对
Retrieved_Gtid_Set和Executed_Gtid_Set差值,差多少就缺多少事务
区分 I/O 停和 SQL 停的修复路径
两者原因和解法完全不同,混用会扩大问题。
- I/O 停(
Slave_IO_Running: No):优先检查telnet 主库IP 3306、主库SELECT user, host FROM mysql.user WHERE replication slave权限、从库/var/lib/mysql/auto.cnf中server-uuid是否与主库重复 - SQL 停(
Slave_SQL_Running: No):禁用sql_slave_skip_counter直接跳过(尤其 GTID 模式下完全无效);应先用SET GTID_NEXT='xxx-xxx'+ 空事务绕过,或导出主库当前一致快照重搭从库 - 若
Seconds_Behind_Master是NULL且Slave_SQL_Running_State显示Waiting for gtid event from coordinator,这其实是正常等待,不是卡住——要看 GTID 集合差值是否增长
重做从库前必须清空 gtid_purged
这是最容易被忽略的致命细节。即使执行了 RESET SLAVE ALL,gtid_purged 的值仍保留旧记录。
- 导入新数据后直接
START SLAVE,MySQL 会认为那些 GTID 对应的事务“已经执行过”,于是跳过所有后续事件,复制瞬间停住 - 正确操作是:导入 dump 后,先
SET GLOBAL gtid_purged = '新值'(即 dump 文件开头的SET @@GLOBAL.gtid_purged行内容),再START SLAVE - 如果 dump 没带
--set-gtid-purged=ON,需手动从主库SHOW MASTER STATUS获取Executed_Gtid_Set并赋值











