innotop无法直接查看死锁日志原文或完整事务上下文,需结合InnoDB Locks/Transactions视图定位阻塞链,并依赖错误日志获取真实死锁快照,辅以IO视图分析诱因,MySQL 8.0+应使用performance_schema.data_lock_*表替代已移除的INNODB_LOCKS相关表。

直接用 innotop 无法看到死锁日志原文或事务的完整上下文,它本身不解析错误日志、也不展示 SHOW ENGINE INNODB STATUS 中的 LATEST DETECTED DEADLOCK 段落。它的作用是实时交互式监控,需配合手动切换视图+外部日志分析才能完成死锁归因。
进入事务与锁视图联动排查
启动 innotop 后默认是 Dashboard(概览页),必须主动切换才能定位阻塞源头:
- 按 l(小写 L)进入 InnoDB Locks 视图:查看所有当前持有的锁和等待中的锁,关键字段包括
lock_trx_id(持锁事务ID)、lock_mode(X/S/REC_NOT_GAP等)、lock_table和lock_index - 按 t 切换到 InnoDB Transactions 视图:找到状态为
LOCK WAIT的事务,对照其trx_id与锁视图中的lock_trx_id是否匹配 - 若发现某事务的
trx_wait_started时间较早,且trx_query显示一条 UPDATE/DELETE,而另一事务正持有它需要的行锁 —— 这就是典型的阻塞链起点
结合错误日志读取真实死锁快照
innotop 不读取错误日志,但死锁的完整现场只存在于 MySQL 错误日志中。需提前配置并定期检查:
- 确认已启用:
SET GLOBAL innodb_print_all_deadlocks = ON;或在my.cnf中添加innodb_print_all_deadlocks = 1 - 查日志路径:
SHOW VARIABLES LIKE 'log_error';,然后用tail -f /var/log/mysql/error.log | grep -i "deadlock"实时捕获 - 每次死锁记录包含两个事务的完整加锁顺序、SQL语句、锁类型(如
RECORD LOCKS space id X page no Y index PRIMARY)、以及哪方被回滚(WE ROLL BACK TRANSACTION)
用 innotop 的 IO 视图辅助判断锁争用诱因
某些“伪死锁”现象实际由 I/O 延迟放大锁等待时间导致。按 i 进入 InnoDB I/O 视图,重点关注:
-
ibuf_merges持续高于ibuf_size:插入缓冲频繁合并,可能拖慢二级索引写入,间接延长事务持锁时间 -
log_writes / log_fsyncs比值异常高(如 >10):日志刷盘滞后,innodb_flush_log_at_trx_commit=2或磁盘响应慢都可能导致事务提交变慢,增加锁冲突窗口 -
pages_read突增 +buffer_pool_hit_ratio骤降(如跌破 85%):说明大量物理读,可能有未走索引的全表扫描正在抢夺 buffer pool 资源,加剧并发争用
MySQL 8.0+ 替代方案补充验证
由于 INFORMATION_SCHEMA.INNODB_LOCKS 和 INNODB_LOCK_WAITS 在 MySQL 8.0 已移除,建议在 innotop 观察到异常后,立即执行以下查询交叉验证:
- 查活跃事务:
SELECT * FROM information_schema.INNODB_TRX WHERE trx_state = 'LOCK WAIT' OR trx_started < NOW() - INTERVAL 30 SECOND; - 查锁等待关系:
SELECT * FROM performance_schema.data_lock_waits;(关联THREAD_ID可查出对应会话的 SQL) - 查锁详情:
SELECT * FROM performance_schema.data_locks WHERE LOCK_TRX_ID IN (SELECT trx_id FROM information_schema.INNODB_TRX WHERE trx_state = 'LOCK WAIT');


















