最直接查锁等待关系是查询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);
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
输

要长期捕获死锁,需启用参数:
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