SHOW FULL PROCESSLIST可直接定位锁等待问题:重点查看State为Waiting for row lock等、Time>60且Info显示正常短SQL的线程,再结合INNODB_LOCK_WAITS查出blocking_query定位真凶。

直接看 SHOW FULL PROCESSLIST 里的 Waiting 状态
慢 SQL 本身可能不报错,但它执行时间长,导致事务迟迟不提交,其他事务想更新同一行时就会卡在 Waiting for row lock 或 Waiting for table metadata lock。这不是死锁,但比死锁更隐蔽——它不会触发 InnoDB 自动回滚,只默默排队。
执行 SHOW FULL PROCESSLIST 后重点关注三列:
-
State:出现Waiting for row lock、Waiting for table metadata lock、Locked就是信号 -
Time:值很大(比如 >60),说明这个等待已经持续很久 -
Info:被阻塞的 SQL 语句本身往往很短、很“正常”,比如UPDATE order SET status=2 WHERE id=12345—— 它不是慢 SQL,只是受害者
用 information_schema.INNODB_LOCK_WAITS 找出谁在挡路
这张表能直接告诉你“谁在等”和“谁在拦”。只要当前有锁等待,它就有记录。
执行:
SELECT r.trx_id waiting_trx_id, r.trx_mysql_thread_id waiting_thread, r.trx_query waiting_query, b.trx_id blocking_trx_id, b.trx_mysql_thread_id blocking_thread, b.trx_query 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;
关键点:
-
blocking_query字段里那条 SQL,大概率就是慢 SQL(或没提交的事务) - 如果
blocking_query是NULL,说明持有锁的事务没在执行 SQL,可能只是开了事务后“睡着了”(比如应用代码里beginTransaction()后忘了commit()) - 注意
blocking_thread对应的线程 ID,可回SHOW FULL PROCESSLIST查它的Time和Command,确认是否长期空闲
对比 Rows_examined 和 Lock_time 判断是否慢 SQL 引发锁竞争
从慢查询日志(mysql.slow_log 表或文件)里捞出最近的慢 SQL,重点看这两列:
-
Rows_examined远大于Rows_sent(比如查 1 行却扫了 50 万行)→ 索引失效,扫描范围大 → 加锁范围也大 → 更容易锁住别人 -
Lock_time占Query_time比例高(比如总耗时 8s,其中 7.5s 在等锁)→ 说明它自己也被别的慢 SQL 或长事务堵住了,形成连锁等待
这种 SQL 不一定出现在 INNODB_LOCK_WAITS 里(因为它可能已执行完),但它在历史中制造过大量锁,是“间接元凶”。排查时不能只盯当前阻塞链,得翻日志看过去一小时谁扫得最多、谁 hold 事务最久。
为什么 SHOW ENGINE INNODB STATUS 的 TRANSACTIONS 部分必须手动翻
SHOW ENGINE INNODB STATUS\G 输出里 TRANSACTIONS 小节会列出所有活跃事务,包括那些没在执行 SQL 但还开着的事务。很多人只扫一眼 LATEST DETECTED DEADLOCK 就跳过了,其实真正的问题藏在这儿:
- 找
trx_state: RUNNING但trx_started时间很早(比如 10 分钟前)的事务 → 它很可能没提交 - 看
trx_isolation_level:如果是REPEATABLE READ,且事务里执行过SELECT ... FOR UPDATE,那它持有的间隙锁可能正卡着后续插入 -
trx_rows_locked和trx_rows_modified值异常高 → 说明它改/锁了大量数据,影响面广
这类事务往往没有对应的应用线程在 PROCESSLIST 里活跃(状态可能是 Sleep),但它的锁一直挂着。这是最容易被忽略的间接锁源——它不慢,但它“赖着不走”。


















