sys.innodb_lock_waits视图能直接看到“谁在等谁”,通过waiting_pid和blocking_pid字段快速定位阻塞源头,是mysql 5.7+最直白的锁等待链路入口,但仅反映活跃的innodb行级锁等待,不包含mdl锁或已释放锁。

sys.innodb_lock_waits 视图能直接看到谁在等、谁在堵
MySQL 8.0 安装 sys schema 后,sys.innodb_lock_waits 是最省事的入口——它把阻塞关系、表名、进程 ID 都揉在一起了,不用手动 JOIN 多张表。执行 SELECT * FROM sys.innodb_lock_waits; 就能立刻看到 waiting_pid 和 blocking_pid 两列,后者就是你要 kill 的目标。
注意:sys.innodb_lock_waits 只在有活跃锁等待时才返回数据;如果业务卡住但该视图为空,说明不是“等待态锁冲突”,可能是长事务持锁未被等(比如刚 BEGIN 就挂起),也可能是 I/O 或网络问题,别硬刷这个视图。
- 该视图依赖
performance_schema开启且相关 instruments 已启用,否则全为空 -
blocking_pid对应的是information_schema.PROCESSLIST.Id,不是线程 ID,可直接用于KILL - 字段
locked_table显示的是被争抢的表,但不反映锁粒度(行锁/间隙锁/MDL)
查不到 blocking_pid?得补查 INNODB_TRX + data_locks
很多情况下 sys.innodb_lock_waits 返回空,但业务明显卡住——这时大概率是“持有锁但无人等待”的长事务,比如一个 BEGIN 后没 COMMIT 的连接,在 INNODB_TRX 里安静躺着,TRX_STATE 是 RUNNING 或 LOCK WAIT,TRX_STARTED 时间很早。
配合 performance_schema.data_locks 才能确认它到底锁了什么:
- 先查
SELECT TRX_ID, TRX_MYSQL_THREAD_ID, TRX_QUERY, TRX_STARTED FROM information_schema.INNODB_TRX ORDER BY TRX_STARTED LIMIT 5;找出最早开始的几个事务 - 再用
TRX_ID去关联performance_schema.data_locks:SELECT OBJECT_SCHEMA, OBJECT_NAME, LOCK_TYPE, LOCK_MODE, LOCK_DATA FROM performance_schema.data_locks WHERE ENGINE_TRANSACTION_ID = 'xxx'; -
LOCK_DATA在唯一主键行锁下才有意义;如果是NULL或显示范围值(如7, 10),大概率是间隙锁或非唯一索引锁,不能直接定位单行
KILL 之前必须区分锁类型:MDL 锁杀错线程没用
看到 Waiting for table metadata lock 报错,别急着 kill 执行 SELECT 的会话——它只持 MDL 读锁,真正堵住 DDL(如 ALTER TABLE)的是后续试图升级写锁的会话。此时 sys.schema_table_lock_waits 才是正解,它专盯元数据锁。
而 sys.innodb_lock_waits 只管 InnoDB 行锁/间隙锁,对 MDL 完全无感。混用会导致:kill 了 SELECT 线程,DDL 还卡着,因为锁源其实是那个正在执行 ALTER 的会话自己卡在等读锁释放。
- MyISAM 表锁:kill 持锁线程通常立即生效
- InnoDB 行锁:kill 持锁事务线程后,锁自动释放
- MDL 锁:必须 kill 正在申请写锁(如 DDL)或持有写锁(如长时间未提交的 DML+DDL 混合事务)的会话
别信 PROCESSLIST 的 Time 字段,TRX_STARTED 才是真相
information_schema.PROCESSLIST.Time 是连接空闲秒数,不是事务运行时长。一个 Sleep 状态但 Time=3600 的连接,可能早就提交了事务;而另一个 Time=2 的 Query 状态连接,如果 TRX_STARTED 是 10 分钟前,那它才是真凶。
所以排查路径必须是:先查 INNODB_TRX 算真实持续时间 TIMESTAMPDIFF(SECOND, TRX_STARTED, NOW()),再结合 TRX_ROWS_LOCKED > 1000 或 TRX_WAITING_TRX_ID IS NOT NULL 判断是否已造成影响。
容易忽略的一点:云数据库(如阿里云 RDS)常限制 SHOW PROCESSLIST 权限,但 INNODB_TRX 和 data_locks 一般仍可查,只要账号有 PROCESS 或 CONNECTION_ADMIN 权限。











