我遇到的一个有趣的案例时,InnoDB间隙锁死锁问题是一个顾客排除在外。在非插入的写操作,没有任何线WHERE子句匹配,我认为交易不应该有一个锁,但是我错了。让我们在这张桌子上一看,例如更新。






显示创建表首选项
*************************** 1。行***************************
表:偏好
创建表:首选项
` numericid ` int(10)符号的非空,
` receivenotifications ` tinyint(1)默认为空,
主键(` numericid `)
InnoDB引擎=默认的字符集latin1)
1行集(0秒)
开始;
查询OK,0行受影响(0秒)
从首选项中选择计数(*);
---------- + +
|计数(*)|
---------- + +
0 | |
---------- + +
1行集(0.01秒)
MySQL >更新设置receivenotifications = '1'where numericid = 2;
查询OK,0行受影响(0.01秒)
匹配行:0更改:0个警告:0



InnoDB的状态表明该更新持有X锁在主索引记录:






——交易活跃4a18101,12秒
2锁结构(s)、堆大小376, 1行锁(s)
MySQL线程ID 3,OS线程句柄0x7ff2200cd700,查询ID 35本地msandbox
TRX阅读视图不会看到TRX ID 4a18102看到4a18102 > <。
表锁表`测试`。`偏好` TRX ID 4a18101 IX锁模式
记录锁空间ID 31766页NO 3 n位72索引表的'主'





为什么会这样Heikki解释它的错误报告。这是非常有意义的。我知道这很难修复,但我讨厌它,我希望它能有所区别。下一mysql1是第一届。mysql2是另一个。查询顺序如下:






mysql1 >开始;
查询OK,0行受影响(0秒)
mysql1 >更新设置receivenotifications = '1'where numericid = 1;
查询OK,0行受影响(0秒)
匹配行:0更改:0个警告:0
mysql2 >开始;
查询OK,0行受影响(0秒)
mysql2 >更新设置receivenotifications = '1'where numericid = 2;
查询OK,0行受影响(0秒)
匹配行:0更改:0个警告:0
mysql1 >插入偏好(numericid,receivenotifications)值(1,1);--这一ES
mysql2 >插入偏好(numericid,receivenotifications)值(2,1);
错误1213(40001):在试图获取锁时发现死锁;尝试重新启动事务



现在你看到它是多么容易导致死锁,所以一定要避免这种情况,如果从插入事务的插入部分可能导致不写操作没有任何行字匹配,不用更换,或read-committed事务隔离。