SHOW PROCESSLIST无法准确识别锁持有者,因其不显示Sleep状态下的隐式事务、元数据锁详情及行级锁信息,需结合INNODB_TRX、INNODB_LOCK_WAITS等视图交叉关联分析才能准确定位真实阻塞源。

show processlist 看不到真正的锁持有者
SHOW PROCESSLIST 只显示线程当前的 State 和 Info,但很多锁问题根本不会在这里暴露:比如一个事务已提交但未释放元数据锁(Waiting for table metadata lock),或者它正持有一个行锁却处于 Sleep 状态——此时 Time 很小、Command 是 Sleep,SHOW PROCESSLIST 会直接把它过滤掉。更麻烦的是,INFO 字段在权限受限或语句超长时为 NULL,你连它执行过什么都看不到。
metadata lock 和 innodb 行锁信息完全缺失
SHOW PROCESSLIST 不区分锁类型,也压根不告诉你谁在等什么锁。真正卡住系统的往往是 metadata lock(比如 ALTER TABLE 正在等一个 SELECT 完结),但它只在 State 里写成模糊的 Waiting for table metadata lock,没 ID、没阻塞源。而 InnoDB 行级锁信息,得靠 INFORMATION_SCHEMA.INNODB_TRX、INNODB_LOCK_WAITS 这些表才能查到谁在等谁、哪个事务 hold 住了哪几行。MySQL 8.0 后还多了 performance_schema.data_lock_waits,但这些全都不在 PROCESSLIST 里。
kill 掉 visible 线程后负载不降,说明你在杀症状
- 看到一个
State是Locked的线程,KILL它,但 CPU/IO 还是高——大概率它只是几十个排队者之一,真正 hold 锁的线程可能早已Sleep或Commit了 - 有些线程
KILL后触发大事务回滚,反而加剧磁盘写压力,LOAD短暂冲更高 -
max_connections被占满时,新请求卡在连接层,PROCESSLIST里全是Connect或Handshake,根本没 SQL 可查
替代方案必须组合使用
单靠 SHOW PROCESSLIST 就像只用体温计查癌症。真要定位锁瓶颈,得立刻切到这几个命令:
查当前活跃事务:SELECT * FROM INFORMATION_SCHEMA.INNODB_TRX ORDER BY TRX_STARTED;
查谁在等锁:SELECT * FROM INFORMATION_SCHEMA.INNODB_LOCK_WAITS;
查锁冲突详情(MySQL 8.0):SELECT * FROM performance_schema.data_lock_waits;
看最近死锁快照:SHOW ENGINE INNODB STATUS\G(注意末尾的 LATEST DETECTED DEADLOCK 块)
这些结果之间要能互相关联 ID(比如 TRX_ID ↔ BLOCKING_TRX_ID),否则你拿到的只是一堆碎片信息。
真正难的不是执行哪条命令,而是把 INNODB_TRX 里的事务、INNODB_LOCK_WAITS 里的等待关系、PROCESSLIST 里的客户端 IP 和 user 对上号——漏掉任意一环,就容易误杀、误判、反复踩坑。


















