最直接查锁等待关系是查询INFORMATION_SCHEMA.INNODB_LOCK_WAITS表,获取requesting_trx_id和blocking_trx_id,再关联INNODB_TRX查具体SQL;MySQL 8.0起应改用performance_schema.data_lock_waits和data_locks;死锁详情通过SHOW ENGINE INNODB STATUS\G查看,长期捕获需启用innodb_print_all_deadlocks=ON并查错误日志。

查当前锁等待关系
最直接的方式是查 INFORMATION_SCHEMA.INNODB_LOCK_WAITS 表,它明确记录了谁在等谁:
SELECT * FROM INFORMATION_SCHEMA.INNODB_LOCK_WAITS;
结果里有两个关键字段:requesting_trx_id(等待方事务 ID)和 blocking_trx_id(阻塞方事务 ID)。
再关联 INNODB_TRX 表就能看到具体 SQL 和事务状态:
SELECT trx_id, trx_state, trx_started, trx_mysql_thread_id, trx_query
FROM INFORMATION_SCHEMA.INNODB_TRX
WHERE trx_id IN (SELECT blocking_trx_id FROM INFORMATION_SCHEMA.INNODB_LOCK_WAITS);
MySQL 8.0 推荐用 performance_schema
INNODB_LOCKS 表已在 8.0 中移除,建议改用 performance_schema.data_lock_waits 和 data_locks:
- 查所有锁:SELECT OBJECT_NAME, LOCK_TYPE, LOCK_MODE, OWNER_THREAD_ID FROM performance_schema.data_locks WHERE OBJECT_SCHEMA = 'your_db';
- 查锁等待链:
SELECT r.OBJECT_NAME AS table_name,
r.LOCK_MODE AS requested_mode,
b.LOCK_MODE AS blocking_mode,
r.OWNER_THREAD_ID AS waiting_thread,
b.OWNER_THREAD_ID AS blocking_thread
FROM performance_schema.data_lock_waits w
JOIN performance_schema.data_locks r ON w.REQUESTING_ENGINE_LOCK_ID = r.ENGINE_LOCK_ID
JOIN performance_schema.data_locks b ON w.BLOCKING_ENGINE_LOCK_ID = b.ENGINE_LOCK_ID;
看最近一次死锁详情
执行命令:
SHOW ENGINE INNODB STATUS\G
输出中重点关注 LATEST DETECTED DEADLOCK 区块,里面包含:
- 涉及的两个事务 ID 和活跃时间
- 各自持有的锁(HOLDS THE LOCK(S))
- 各自等待的锁(WAITING FOR THIS LOCK TO BE GRANTED)
- 触发死锁的具体 SQL 语句
注意:该命令只保留最近一次死锁,不能回溯历史。
开启并查看死锁日志
要长期捕获死锁,需启用参数:
SET GLOBAL innodb_print_all_deadlocks = ON;
(无需重启,但仅对后续死锁生效)
死锁信息会写入 MySQL 错误日志,路径可通过以下命令确认:
SHOW VARIABLES LIKE 'log_error';
常见路径如 /var/log/mysql/error.log,用 grep 快速定位:
grep -A 20 "LATEST DETECTED DEADLOCK" /var/log/mysql/error.log










