查锁表用show open tables where in_use > 0快速定位被占用表;查锁事务用information_schema.innodb_trx看持锁线程;查锁等待链用innodb_lock_waits定位阻塞关系;辅以show full processlist验证状态并杀线程。

查锁表:用 SHOW OPEN TABLES 快速定位被占用的表
这个命令最轻量,适合第一眼判断“是不是有表被锁住了”。IN_USE > 0 表示该表当前正被某个线程使用或锁定(注意:不是所有 IN_USE=1 都代表异常,比如正常读写也会触发,但持续为 1 就值得盯)。
-
SHOW OPEN TABLES WHERE IN_USE > 0;—— 只看真正“在用”的表,避免干扰 - 结果中
Table列是表名,Database列是库名,结合业务快速定位问题模块 - ⚠️ 坑:MyISAM 表会显示
IN_USE=1即使只是简单SELECT;InnoDB 表则更依赖事务级锁,这里可能“不显形”,不能只靠它下结论
查锁事务:INFORMATION_SCHEMA.INNODB_TRX 看谁在持锁
这才是 InnoDB 锁问题的核心入口。它列出所有**正在运行的事务**,包括还没提交、正在等锁、甚至卡住的长事务。
-
SELECT * FROM INFORMATION_SCHEMA.INNODB_TRX\G—— 加\G让输出更可读,重点关注:trx_state(LOCK WAIT表示正在等锁)、trx_started(判断是否长事务)、trx_query(当前执行的 SQL) -
trx_mysql_thread_id是 kill 的关键 ID,不是PROCESSLIST里的ID,但两者通常一致 - ⚠️ 坑:普通用户默认查不到其他用户的事务,需被授予
PROCESS权限;若没权限,SHOW PROCESSLIST只能看到自己线程,容易误判“没锁”
查锁等待链:INNODB_LOCK_WAITS 找出谁堵了谁
当出现明显阻塞(比如某条 UPDATE 卡住几十秒),这个视图能直接告诉你“谁在等、等谁、被谁拦着”。
SELECT r.trx_id AS waiting_trx_id, r.trx_mysql_thread_id AS waiting_thread, r.trx_query AS waiting_query, b.trx_id AS blocking_trx_id, b.trx_mysql_thread_id AS blocking_thread, b.trx_query AS blocking_query FROM INFORMATION_SCHEMA.INNODB_LOCK_WAITS w INNER JOIN INFORMATION_SCHEMA.INNODB_TRX b ON b.trx_id = w.blocking_trx_id INNER JOIN INFORMATION_SCHEMA.INNODB_TRX r ON r.trx_id = w.requesting_trx_id;- 结果里
waiting_query和blocking_query对比一看就明白冲突点在哪(比如一个在更新user表主键,另一个在更新同一行的status字段) - ⚠️ 坑:
INNODB_LOCK_WAITS是瞬时快照,如果锁已释放,它就为空——所以得在卡顿发生时立刻查,别等“稍后再看”
查进程状态:SHOW PROCESSLIST 辅助验证和杀线程
它不直接显示锁,但能告诉你线程在干什么、卡在哪一步,是配合前面几个视图做闭环判断的最后一步。
-
SHOW FULL PROCESSLIST;—— 加FULL才能看到完整 SQL(否则可能被截断) - 关注
State列:Updating、Locked、Sending data、Waiting for table metadata lock都可能是锁相关信号 - 杀线程用
KILL <code>thread_id;,注意:只能杀自己线程(除非有SUPER权限);杀错可能中断业务事务,先确认trx_query再动手
真实场景里,锁问题往往不是单点故障,而是“长事务 + 无索引查询 + 高频轮询”叠加出来的。比如前端每秒调一个没加索引的 SELECT COUNT(*) FROM order WHERE status=1 AND create_time > 'xxx',它会扫全表、持 MDL 锁、拖慢后续 DML——这种问题光看 INNODB_TRX 可能只看到“等待”,得结合 PROCESSLIST 的 State 和慢日志才能揪出根因。










