要查看MySQL锁等待,需结合
与SHOW ENGINE INNODB STATUS中information_schemainnodb_trx、、innodb_locksinnodb_lock_waits表;首先通过获取死锁及事务等待概览,再查询SHOW ENGINE INNODB STATUSinnodb_trx定位处于状态的事务,接着利用LOCK WAITinnodb_lock_waits关联等待与阻塞事务,最后通过分析锁类型与资源,从而完整还原锁等待链路。innodb_locks

要查看MySQL中的锁等待情况,核心在于利用
information_schema
数据库中的
innodb_trx
、
innodb_locks
和
innodb_lock_waits
这几个表,同时
SHOW ENGINE INNODB STATUS
命令也是一个不可或缺的强大工具,它能提供非常详尽的InnoDB引擎状态报告,包括最新的死锁信息和当前正在等待的事务。
在我的日常运维和开发中,当MySQL出现性能瓶颈,尤其是并发量上去之后,锁等待几乎是绕不开的话题。定位这些问题,我通常会从几个角度入手。
首先,
SHOW ENGINE INNODB STATUS
是一个非常全面的诊断命令。它会输出一大段文本,里面包含了InnoDB引擎的各种运行时状态。我最常关注的几个部分是:
- LATEST DETECTED DEADLOCK: 如果系统发生了死锁,这里会详细记录死锁的事务ID、SQL语句、锁类型以及等待的资源。这是定位死锁的黄金信息。
- TRANSACTIONS: 这个部分会列出当前活跃的事务,包括它们的状态(
RUNNING,等)、执行的SQL语句、事务ID以及持有或正在等待的锁。如果你看到某个事务的状态是LOCK WAITLOCK WAIT,那基本上就找到线索了。
例如,查看完整的InnoDB状态报告:
SHOW ENGINE INNODB STATUS;
其次,对于更精细、更便于程序化查询的锁等待信息,
information_schema
数据库中的几个表是我的首选:
-
.information_schemainnodb_trx: 这个表记录了所有当前正在运行的InnoDB事务。它的
trx_state字段会明确指出事务是
RUNNING、
LOCK WAIT还是其他状态。
trx_query则显示了事务正在执行的SQL语句。
SELECT trx_id,
trx_state, trx_started, trx_requested_lock_id, trx_wait_started, trx_mysql_thread_id,trx_queryFROM.information_schemainnodb_trxWHEREtrx_state= '';LOCK WAIT通过这个查询,我能迅速找出哪些事务正处于等待状态,以及它们在执行什么操作。
-
.information_schemainnodb_locks: 这个表展示了InnoDB引擎当前持有的所有锁以及正在请求的锁。
lock_mode会告诉你锁的类型(S, X, IS, IX等),
lock_type则指明了是行锁还是表锁。
SELECT lock_id, lock_trx_id,
lock_mode,lock_type, lock_table, lock_index, lock_data FROM.information_schema;innodb_locks这个表虽然能看到锁的详细情况,但它本身并不能直接告诉你哪个锁在等待哪个锁。
-
.information_schemainnodb_lock_waits: 这是我个人觉得最直接、最有用的表,它清晰地展示了锁等待的关系。它连接了
innodb_locks表,明确指出哪个事务(
requesting_trx_id)正在等待哪个锁(
requested_lock_id),以及哪个事务(
blocking_trx_id)持有了这个锁(
blocking_lock_id)。
SELECT t.trx_id AS waiting_trx_id, t.trx_mysql_thread_id AS waiting_thread, t.
trx_queryAS waiting_query, b.trx_id ASblocking_trx_id, b.trx_mysql_thread_id AS blocking_thread, b.trx_queryAS blocking_query, lw.requesting_lock_id, lw.blocking_lock_idFROM.information_schemainnodb_lock_waitslw JOIN.information_schemainnodb_trxt ON lw.requesting_trx_id= t.trx_id JOIN.information_schemainnodb_trxb ON lw.blocking_trx_id=


