slave_sql_running_state仅反映复制线程状态快照,需结合show full processlist(查system user的info)、innodb_trx(定位lock wait事务)及innodb_lock_waits(分析锁等待关系)交叉验证才能准确定位卡住语句。

从库卡住时,Slave_SQL_Running_State 显示的不是 SQL 本身,而是复制线程当前在做什么;要定位真正卡住的语句,得结合它 + SHOW PROCESSLIST + INFORMATION_SCHEMA.INNODB_TRX 三处交叉验证。
怎么看 Slave_SQL_Running_State 的真实含义
这个字段来自 SHOW SLAVE STATUS\G 输出,但它只是复制线程的“状态快照”,不是执行中的 SQL。比如:
-
Reading event from the relay log:还没开始执行,只是在读中继日志 -
Waiting for an event from Coordinator:并行复制下等待调度,不表示卡死 -
Updating或Sending data:可能真在执行某条语句,但具体哪条?Info列为空,无法直接看到 -
Waiting for commit lock或Waiting for table metadata lock:说明被锁住了,但锁谁?得查锁表
所以单看这个字段,只能判断“是否停滞”,不能定位“哪条 SQL 卡住”。
用 SHOW FULL PROCESSLIST 找出 SQL 线程的实时语句
MySQL 从库的 SQL 线程是一个普通连接,ID 固定为 system user,Command 是 Connect,但它的 Info 字段会显示正在执行的语句(前提是没被截断):
mysql> SHOW FULL PROCESSLIST; +----+-------------+-----------------+------+---------+------+--------------------------------+-------------------------------------------------------------------+ | Id | User | Host | db | Command | Time | State | Info | +----+-------------+-----------------+------+---------+------+--------------------------------+-------------------------------------------------------------------+ | 4 | system user | | NULL | Connect | 1823 | Waiting for table metadata lock| UPDATE orders SET status = 'shipped' WHERE id = 123456789 | +----+-------------+-----------------+------+---------+------+--------------------------------+-------------------------------------------------------------------
关键点:
- 只看
User = 'system user'且Command = 'Connect'的那行 - 必须用
SHOW FULL PROCESSLIST,否则Info被截断(默认只显示前 100 字) - 如果
Info是NULL,说明语句已执行完或刚进入等待状态,得继续查锁
查 INFORMATION_SCHEMA.INNODB_TRX 确认事务级阻塞
从库卡住,90% 是因为某条事务在等锁。这时 INNODB_TRX 比 PROCESSLIST 更可靠:
SELECT trx_id, trx_mysql_thread_id, trx_state, trx_started, trx_query FROM INFORMATION_SCHEMA.INNODB_TRX WHERE trx_state = 'LOCK WAIT';
输出里 trx_query 就是真正卡住的语句,trx_mysql_thread_id 对应 PROCESSLIST 中的 Id。如果查不到 LOCK WAIT,但复制仍停滞,可能是:
- DDL 操作(如
ALTER TABLE)持有 MDL 锁,需查performance_schema.metadata_locks(MySQL 5.7+) - 主库 binlog 写入慢或网络延迟,导致中继日志没更新,此时
Seconds_Behind_Master持续增长但Slave_SQL_Running_State显示正常 - 从库磁盘 I/O 拖累,
State可能长期停在Reading event from the relay log
别漏掉 INNODB_LOCK_WAITS 定位谁在堵谁
当确认有锁等待时,用这个联查能直接看到“谁堵了谁”:
SELECT r.trx_query AS waiting_query, b.trx_query AS blocking_query FROM INFORMATION_SCHEMA.INNODB_LOCK_WAITS w JOIN INFORMATION_SCHEMA.INNODB_TRX b ON b.trx_id = w.blocking_trx_id JOIN INFORMATION_SCHEMA.INNODB_TRX r ON r.trx_id = w.requesting_trx_id;
注意:
- 这个视图只在 InnoDB 有活跃锁等待时才返回结果
- 如果
blocking_query是NULL,说明阻塞源是隐式锁(比如唯一键冲突)或外部进程(如另一个客户端手动加了LOCK TABLES) - 从库上出现
blocking_query来自主库的 DML,基本可断定是主从不一致或从库本地事务未提交
真正卡住的从来不是那条 SQL 语句本身,而是它依赖的锁、资源或上游状态。盯住 Slave_SQL_Running_State 只是起点,下一步必须跳到线程、事务、锁三层去对齐信息——少一层,就容易 kill 错线程或优化错语句。











