InnoDB是否将整个表锁定为使用组合键的一部分进行删除?

时间:2018-10-26 16:06:33

标签: mysql locking innodb

我有一个MySQL表(称为“ my_table”),该表具有由4列组成的主键(称为“ a”,“ b”,“ c”和“ d”)。

至少有一次我在并行异步EJB调用上遇到死锁,该调用调用'从my_table中删除,其中a =?和b =?'使用不同的值,因此我开始研究InnoDB表锁定的工作方式。

我找不到关于表锁定如何与组合键一起工作的清晰文档。整个表是否被删除锁定了,尽管实际删除的行之间没有重叠?

我是否需要进行选择以恢复c和d的值并使用整个主键删除批次?

这是在一个复杂的应用程序的上下文中,该应用程序可以使用4个不同的数据库。只有MySQL似乎有此问题。

1 个答案:

答案 0 :(得分:1)

InnoDB永远不会为DML语句锁定整个表。 (除非DML命中了所有行。)

DDL语句还有其他锁,例如ALTER TABLE修改/添加列/索引/等时。 (其中一些已经在MySQL 8.0中大大加快了。)

关于复合键的锁定没有什么特别的。

有一种叫做“间隙锁”的东西。由于各种原因,索引中两个值之间的“间隙”将被锁定。这样可以避免潜在的冲突,例如插入尚不存在的相同 new 值,并且存在唯一性约束。

由于PRIMARY KEY是唯一键,因此您可能命中了类似的内容。

如果可行,请执行SHOW ENGINE INNODB STATUS;来查看锁是否为“间隙”。

可能发生的另一件事是,锁可能开始是弱锁,然后升级为“ eXclusive”。这可能导致死锁。

  

我是否需要进行选择以恢复c和d的值并使用整个主键删除批次?

我认为您需要更准确地解释自己在做什么。提供查询。提供SHOW CREATE TABLE

InnoDB的锁处理可能是MySQL特有的。它有一些怪癖。有时,它对锁定的内容有点贪婪。作为补偿,它可能比竞争对手更快。

无论如何,请检查死锁(和超时)并进行处理。希望这些问题非常罕见,以至于必须解决这些问题不会对性能造成太大负担。

DELETE FROM my_table where a=? and b=?意味着可能要删除大量行。这意味着撤消日志和MVCC需要做很多工作。因此,建议不要一次删除(或更新)超过1K行。