为啥这是一个死锁(MySQL 使用 InnoDB)
Posted
技术标签:
【中文标题】为啥这是一个死锁(MySQL 使用 InnoDB)【英文标题】:Why is this a deadlock (MySQL using InnoDB)为什么这是一个死锁(MySQL 使用 InnoDB) 【发布时间】:2011-04-18 08:53:38 【问题描述】:SHOW INNODB ENGINE STATUS 显示这个并称之为死锁:
最新检测到的死锁
100923 22:29:21
* (1) 交易:
事务 0 5335752,活动 0 秒,操作系统线程 id 7992 插入
mysql 表正在使用 1,锁定 1
LOCK WAIT 5 锁结构,堆大小 1024,4 行锁,撤消日志条目 3
MySQL 线程 id 26,查询 id 14422 localhost 127.0.0.1 根更新
插入 history_messagearguments (history_id, messageArguments_ORDER, messageArguments) 值 (69, 1, '1')
* (1) 等待授予此锁定:
RECORD LOCKS space id 0 page no 179145 n bits 304 index fk_history_msgargs
of table zvs_rkl_01_test
.history_messagearguments
trx id 0 5335752 lock_mode X在rec插入意图等待之前锁定间隙
记录锁,堆号 198 物理记录:n_fields 2;紧凑的格式;信息位 0
0:长度 8;十六进制 8000000000000048;升 H;; 1:长度 6;十六进制 0000006fe7c5; asc o ;;
* (2) 交易:
事务 0 5335748,活动 0 秒,操作系统线程 id 6988 插入,线程在 InnoDB 500 内声明
mysql 表正在使用 1,锁定 1
5 个锁结构,堆大小 1024,3 行锁,撤消日志条目 2
MySQL 线程 id 25,查询 id 14424 localhost 127.0.0.1 根更新
插入 history_messagearguments (history_id, messageArguments_ORDER, messageArguments) 值 (71, 0, '0')
* (2) 持有锁:
RECORD LOCKS 空间 id 0 页号 179145 n 位 304 索引 fk_history_msgargs
表 zvs_rkl_01_test
.history_messagearguments
trx id 0 5335748 lock_mode X 在记录之前锁定间隙
记录锁,堆号 198 物理记录:n_fields 2;紧凑的格式;信息位 0
0:长度 8;十六进制 8000000000000048;升 H;; 1:长度 6;十六进制 0000006fe7c5; asc o ;;
* (2) 等待此锁定被授予:
RECORD LOCKS space id 0 page no 179145 n bits 304 index fk_history_msgargs
of table zvs_rkl_01_test
.history_messagearguments
trx id 0 5335748 lock_mode X在rec插入意图等待之前锁定间隙
记录锁,堆号 198 物理记录:n_fields 2;紧凑的格式;信息位 0
0:长度 8;十六进制 8000000000000048;升 H;; 1:长度 6;十六进制 0000006fe7c5; asc o ;;
* 我们回滚交易 (2)
我不明白为什么这是一个死锁。事务 1 没有“WAITING FOR THIS LOCK TO BE GRANTED:”行。如果事务 1 没有持有任何锁,它就不能阻塞任何人,因此它不能成为死锁的一部分。
从理论上讲,我看不到这里写的条件 4 被满足: http://en.wikipedia.org/wiki/Deadlock#Necessary_conditions
在我看来,mysql 应该让事务 2 继续。完成后,事务 1 可以继续进行。
在这里 (http://***.com/questions/1851528/mysql-deadlock-explanation-needed) BrainCore 写道:
事务 2 “卡”在事务 1 的请求后面,一个 FIFO 队列。
谁能指出我的 MySQL 文档来确认这一点?我很难相信交易是严格按照它们到达的顺序执行的。
在有关表布局、隔离级别等的所有问题出现之前:我现在不寻求解决死锁的帮助。请问如何读取SHOW ENGINE STATUS OUTPUT。
【问题讨论】:
【参考方案1】:读取事务 1 和 2: 从头到尾阅读:
什么类型以及为什么:lock_mode X 在记录插入意图等待之前锁定间隙 什么被阻止:记录锁空间 id 0 页号 179145 n 位 304 索引 fk_history_msgargs 表 zvs_rkl_01_test.history_messagearguments trx id 0 5335748 等待授予此锁定权限InnoDB 存在并发写入问题,尤其是当您在 innodb 表的末尾插入数据时。
【讨论】:
如果插入在表的末尾,您能否引用 InnoDB 并发写入问题的说法?尝试对此主题进行更多研究,但很难找到信息。 这篇文章提供了一些额外的证据***.com/questions/50730278/…。以上是关于为啥这是一个死锁(MySQL 使用 InnoDB)的主要内容,如果未能解决你的问题,请参考以下文章