讲师中心 微信公众号
AI工具推荐 视频效率加速

如何在MySQL中利用Show-Engine-Innodb-Status分析行锁冲突的死锁详情

老晨君_4545

老晨君_4545

发布时间:2026-05-01 14:23:19

|

630人浏览过

|

来源于php中文网

原创

SHOW ENGINE INNODB STATUS 的 LATEST DETECTED DEADLOCK 区域记录最后一次死锁详情,含事务ID、锁等待与持有关系、索引名及主键/二级索引值,可定位被锁行但不保存原始SQL,需结合业务逻辑分析并发路径。

如何在mysql中利用show-engine-innodb-status分析行锁冲突的死锁详情

怎么看 SHOW ENGINE INNODB STATUS 里的死锁信息

MySQL 不会主动报出死锁的完整上下文,但每次发生死锁后,SHOW ENGINE INNODB STATUS 会在输出的 LATEST DETECTED DEADLOCK 区域记录最后一次死锁的详细过程。这个区域是唯一能直接看到「谁锁了谁、等什么、为什么卡住」的地方。

执行命令后,重点往下翻,找到以 ---TRANSACTION 开头、紧挨着 LATEST DETECTED DEADLOCK 标题的那一段。它不是日志时间戳,而是两个(或多个)事务的快照对比。

  • 每个 TRANSACTION 块开头会标出事务 ID(如 123456789)、状态(ACTIVE 或 WAITING FOR THIS LOCK TO BE GRANTED)和运行时长
  • mysql tables in use 和 locked in InnoDB 能帮你确认是否真在操作同一张表
  • 关键线索在 WAITING FOR THIS LOCK TO BE GRANTED 后面的 lock_mode X locks rec but not gap waiting —— 这说明它在等一个行级排他锁,且是具体某条记录(不是间隙)
  • 往上找同个事务块里的 HELD LOCK(S),就能看到它自己持有哪些锁;再看另一个事务的 WAITING 和 HELD,就构成死锁环

如何定位到具体哪一行被锁住了

死锁详情里不会直接写 WHERE id = 123,但会给出索引名、主键值(或二级索引值)和记录的物理位置。你需要结合 RECORD LOCKS 行来解码。

例如出现:Record lock, heap no 22 PHYSICAL RECORD: n_fields 5; compact format; info bits 0,后面跟着一串十六进制值 —— 这些就是该记录在索引页中的字段内容。其中最关键的是主键字段(如果是聚簇索引)或二级索引键值。

MySQL
MySQL

编写正确的MySQL查询,避免字符集、索引和锁方面的常见陷阱。

下载
  • 如果表有自增主键 id,通常第二字段(n_fields 5 中的第 2 个)就是 id 的值,以十进制显示在括号里,比如 0x000000000000007B → 123
  • 如果锁在二级索引上(比如 UNIQUE KEY email),则要看 index `email` of table `test`.`users` 后面的字段值,它对应的是 email 字段的字节序列
  • 注意:如果字段是 VARCHAR,值末尾可能带填充空格或长度前缀,不能直接字符串匹配,得按实际存储格式比对

为什么有时候 SHOW ENGINE INNODB STATUS 没有死锁记录

最常见原因是:死锁刚发生完就被清掉了,而你没及时查。MySQL 只保留最后一次死锁信息,且不落盘,重启即失。另外,某些版本(如 MySQL 5.7.20+)默认关闭了死锁日志输出到错误日志的功能,只靠 SHOW 命令抓取。

  • 确保没人在你之前执行过该命令 —— 每次执行都会覆盖上一次的死锁快照
  • 开启 innodb_print_all_deadlocks = ON(需写入配置文件并重启),让所有死锁都记进错误日志,避免遗漏
  • 注意权限:执行 SHOW ENGINE INNODB STATUS 需要 PROCESS 权限,普通应用账号通常没有,得用 DBA 账户查
  • 如果业务中死锁频发但 SHOW 里为空,大概率是死锁被快速解决后又被新死锁覆盖,建议配合慢日志 + 应用层 SQL 日志交叉定位

从死锁信息反推 SQL 语句的局限性

SHOW ENGINE INNODB STATUS 不保存原始 SQL,只记录事务持有的锁和等待目标。你能知道「事务 A 持有主键=123 的 X 锁,等待主键=456 的 X 锁;事务 B 持有 456,等待 123」,但无法 100% 确定它们各自执行的是哪条 UPDATE 或 SELECT ... FOR UPDATE。

  • 如果事务开了自动提交(autocommit=1),那基本可认定每条 DML 就是一个独立事务,锁行为较单纯
  • 如果事务手动控制(BEGIN / COMMIT),就得结合应用代码看:哪几条 SQL 在同一个事务里,顺序如何,中间有没有 SELECT 触发隐式锁
  • 特别注意 INSERT ... ON DUPLICATE KEY UPDATE 和 REPLACE INTO:它们会先加插入意向锁,再加唯一键冲突行的 X 锁,这种组合极易卷入死锁,但日志里只显示最终持有的锁,不体现意图

真正难的不是看懂那段输出,而是把锁行为和业务逻辑里的并发路径对上号。比如两个服务同时处理用户余额,一个走「扣减→校验」,一个走「校验→扣减」,SHOW ENGINE INNODB STATUS 只告诉你「锁住了」,但为什么选这个顺序、能不能改、改了会不会引入新问题——这些得回到代码里看。

热门AI工具

更多
Loomy
Loomy Hot

一款AI工具,主要用于科大讯飞发布的桌面级 AI 助理,比 OpenClaw 更易用、更安全!,适合需要提升相关任务效率的用户。

音述AI
音述AI Hot

一款AI音频处理工具,主要用于音述AI是一个以“用声音述说故事”为核心的 AI 音乐创作与声音分享社区,适合需要提升相关任务效率的用户。

火山引擎

火山引擎是一款面向企业的云计算与AI服务平台。

豆包大模型

豆包大模型是一款由字节跳动推出的企业级大语言模型服务平台。

VibeKnow
VibeKnow Hot

一款AI视频创作工具,主要用于全球首个AI知识视频创作平台,文档、文章、网页,一键生成视频,适合需要提升相关任务效率的用户。

立刻MV
立刻MV Hot

立刻MV是一款AI文本写作工具,AI 音乐视频(MV)创作工具。

DeepSeek

DeepSeek是一款面向对话、写作、编程和推理场景的AI大模型工具。

WorkBuddy

一款AI办公效率工具,主要用于腾讯云推出的AI原生桌面智能体工作台,适合需要提升相关任务效率的用户。

AionClaw
AionClaw Hot

AionClaw是一款面向办公、创作和编程任务的AI桌面智能体。

相关专题

更多
数据库三范式
数据库三范式

数据库三范式是一种设计规范,用于规范化关系型数据库中的数据结构,它通过消除冗余数据、提高数据库性能和数据一致性,提供了一种有效的数据库设计方法。本专题提供数据库三范式相关的文章、下载和课程。

2725

2023.06.29

如何删除数据库
如何删除数据库

删除数据库是指在MySQL中完全移除一个数据库及其所包含的所有数据和结构,作用包括:1、释放存储空间;2、确保数据的安全性;3、提高数据库的整体性能,加速查询和操作的执行速度。尽管删除数据库具有一些好处,但在执行任何删除操作之前,务必谨慎操作,并备份重要的数据。删除数据库将永久性地删除所有相关数据和结构,无法回滚。

3921

2023.08.14

vb怎么连接数据库
vb怎么连接数据库

在VB中,连接数据库通常使用ADO(ActiveX 数据对象)或 DAO(Data Access Objects)这两个技术来实现:1、引入ADO库;2、创建ADO连接对象;3、配置连接字符串;4、打开连接;5、执行SQL语句;6、处理查询结果;7、关闭连接即可。

2991

2023.08.31

MySQL恢复数据库
MySQL恢复数据库

MySQL恢复数据库的方法有使用物理备份恢复、使用逻辑备份恢复、使用二进制日志恢复和使用数据库复制进行恢复等。本专题为大家提供MySQL数据库相关的文章、下载、课程内容,供大家免费下载体验。

967

2023.09.05

vb中怎么连接access数据库
vb中怎么连接access数据库

vb中连接access数据库的步骤包括引用必要的命名空间、创建连接字符串、创建连接对象、打开连接、执行SQL语句和关闭连接。本专题为大家提供连接access数据库相关的文章、下载、课程内容,供大家免费下载体验。

2627

2023.10.09

数据库对象名无效怎么解决
数据库对象名无效怎么解决

数据库对象名无效解决办法:1、检查使用的对象名是否正确,确保没有拼写错误;2、检查数据库中是否已存在具有相同名称的对象,如果是,请更改对象名为一个不同的名称,然后重新创建;3、确保在连接数据库时使用了正确的用户名、密码和数据库名称;4、尝试重启数据库服务,然后再次尝试创建或使用对象;5、尝试更新驱动程序,然后再次尝试创建或使用对象。

2627

2023.10.16

vb连接access数据库的方法
vb连接access数据库的方法

vb连接access数据库方法:1、使用ADO连接,首先导入System.Data.OleDb模块,然后定义一个连接字符串,接着创建一个OleDbConnection对象并使用Open() 方法打开连接;2、使用DAO连接,首先导入 Microsoft.Jet.OLEDB模块,然后定义一个连接字符串,接着创建一个JetConnection对象并使用Open()方法打开连接即可。

2873

2023.10.16

vb连接数据库的方法
vb连接数据库的方法

vb连接数据库的方法有使用ADO对象库、使用OLEDB数据提供程序、使用ODBC数据源等。详细介绍:1、使用ADO对象库方法,ADO是一种用于访问数据库的COM组件,可以通过ADO连接数据库并执行SQL语句。可以使用ADODB.Connection对象来建立与数据库的连接,然后使用ADODB.Recordset对象来执行查询和操作数据;2、使用OLEDB数据提供程序方法等等。

2441

2023.10.19

OpenJDK JVM参数怎么调优
OpenJDK JVM参数怎么调优

Java应用运行缓慢,如何调整JVM参数?本专题介绍OpenJDK JVM性能调优的基本流程,涵盖性能指标确认、运行数据采集、内存配置和垃圾回收分析,帮助你先定位瓶颈,再通过对照测试验证效果,避免直接套用参数而影响应用稳定性。

60

2026.10.16

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
PostgreSQL vs MySQL
PostgreSQL vs MySQL

共1课时 | 188人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn