Exec_Master_Log_Pos卡住但Slave_SQL_Running为Yes,说明SQL线程未崩溃却停滞,常见原因为MDL锁阻塞、单线程回放瓶颈、GTID模式下误判位置或磁盘满导致relay log写入失败,需结合SHOW PROCESSLIST、错误日志、binlog解析及系统资源交叉验证。

Exec_Master_Log_Pos卡住不动,但Slave_SQL_Running是Yes
这说明SQL线程没崩溃,但实际没推进执行位置——它正在死等某个资源。最常见的是表级元数据锁(MDL)阻塞,比如主库刚发来一个ALTER TABLE,而从库上恰好有长事务或未提交查询正持有该表的MDL读锁。
检查方法:在从库执行SELECT * FROM information_schema.innodb_trx WHERE TIME_TO_SEC(NOW() - trx_started) > 60;,再结合SHOW PROCESSLIST找State为Waiting for table metadata lock的线程。别只看Last_SQL_Error,它可能为空,因为还没真正报错。
- 如果发现阻塞源是
SELECT类查询,优先干掉它(KILL <code>thread_id),让DDL继续 - DDL本身无法并行,
Exec_Master_Log_Pos必然停在DDL开始前的位置,直到执行完才跳变 - 确认是否为大事务:用
mysqlbinlog --base64-output=DECODE-ROWS -v mysql-bin.0000xx | grep -A 20 "end_log_pos <code>Exec_Master_Log_Pos"反查该位置对应的语句,大概率是百万行UPDATE无索引
Relay_Log_Space持续增长,但Exec_Master_Log_Pos不变
这暴露了典型的“IO快、SQL慢”失衡:中继日志在疯狂写入,SQL线程却几乎不消费。根本原因不是复制中断,而是单线程回放跟不上节奏。
典型场景包括:主库批量INSERT INTO ... SELECT生成巨量row event;从库innodb_flush_log_at_trx_commit=1且磁盘I/O吞吐不足;或者开了log_slave_updates做级联复制,额外增加解析开销。
- 先看
Slave_SQL_Running_State是否长期停留在Reading event from the relay log——这是单线程瓶颈的明确信号 - 对比主从硬件:从库CPU/IO明显弱于主库时,高并发写入必然堆积
- MySQL 5.7+可启用并行复制:
SET GLOBAL slave_parallel_workers = 4;,但需主库设置binlog_transaction_dependency_tracking = WRITESET,否则无效
Exec_Master_Log_Pos恒为4(GTID模式下)
这不是故障,是GTID模式的正常表现。Exec_Master_Log_Pos在GTID开启后失去意义,固定为4(binlog文件头长度),所有位置信息由Executed_Gtid_Set和Retrieved_Gtid_Set承载。
误判常发生在管理员仍用传统position比对法排查延迟。此时SHOW SLAVE STATUS\G里Exec_Master_Log_Pos不变,纯属设计如此,不代表同步停滞。
- 正确做法:比对
Executed_Gtid_Set与主库SELECT @@global.gtid_executed;,差集即未同步事务 - 若
Retrieved_Gtid_Set不再更新,才是IO线程问题;若两者一致但业务数据未更新,需检查应用层是否误读了GTID范围 - 跳过错误事务必须用
SET GTID_NEXT='xxx'; BEGIN; COMMIT;,严禁用sql_slave_skip_counter(GTID模式下直接报错)
从库磁盘满或relay log损坏导致静默失败
IO线程遇到写relay log失败(如No space left on device或Failed to open relay log),默认行为是静默停止,Slave_IO_Running仍显示Yes,但Read_Master_Log_Pos和Master_Log_Pos彻底冻结。
这种问题极隐蔽:监控看到复制状态全绿,但数据早已不同步。必须主动翻错误日志,不能只信SHOW SLAVE STATUS。
- 立即执行:
tail -n 100 /var/log/mysql/error.log | grep -i -E "(relay|space|fail|error)" - 检查磁盘:
df -h /var/lib/mysql(relay log默认路径) - 验证relay log完整性:
mysqlbinlog --no-defaults mysql01-relay-bin.000092 | head -20,若报Could not read file或输出乱码,说明文件损坏
真正麻烦的从来不是Exec_Master_Log_Pos停在哪,而是它为什么停——背后可能是MDL锁、单线程瓶颈、GTID误读,或是磁盘已满却没人看日志。定位时别被Yes/No状态骗了,得交叉验证Relay_Log_Space、错误日志、binlog内容和系统资源。


















