Mysql 删除操作在innodb中锁定整个表

Mysql 删除操作在innodb中锁定整个表,mysql,innodb,deadlock,Mysql,Innodb,Deadlock,我在InnoDB的删除操作中遇到了表锁定问题。 我有一个表队列,例如一列和许多事务,它们可以将行插入队列或删除行。 没有任何两个事务同时处理同一行。因此,所有行锁必须是不同的。 但有时当删除操作删除表中大部分行时,InnoDB更喜欢使用表锁而不是行锁,这会导致死锁 我不能准确地重现这个死锁,但我发现了锁的问题。 i、 e.我有表队列:id和值(1,3,4,5,6,7) 交易1: insert into queue value(2); 交易2: delete from queue where i

我在InnoDB的删除操作中遇到了表锁定问题。 我有一个表队列,例如一列和许多事务,它们可以将行插入队列或删除行。 没有任何两个事务同时处理同一行。因此,所有行锁必须是不同的。 但有时当删除操作删除表中大部分行时,InnoDB更喜欢使用表锁而不是行锁,这会导致死锁

我不能准确地重现这个死锁,但我发现了锁的问题。 i、 e.我有表队列:id和值(1,3,4,5,6,7)

交易1:

insert into queue value(2);
交易2:

delete from queue where id in (1,3,4,5,6,7); -- here the lock comes

首先,假设id是主键或至少是索引列

Insert不应锁定该表,因此可能在删除记录的同时执行任何其他更新/删除查询

如果情况并非如此,则可能是由于“间隙锁定”,如“一匹没有名字的马”所述

所以,当您再次遇到此问题时,您需要将所有进程“show full processlist”存储在您的端部,并检查“show engine innodb status”,其中将显示与死锁相关的进程ID,这将帮助您了解确切的问题


此外,可以避免这种锁定,根据主键逐个删除所有行

如果我没弄错的话,这是由MySQL的“间隙锁定”造成的:我忘了一件事。我做了一个实验。我在这个表中添加了200行垃圾,表锁和死锁都消失了。@kajetons你说得对。这不是表锁,这是间隙锁。@horse\u有一个没有名字的链接坏了,你能更新它吗?在这里,新链接看起来像是我得到的。我的问题在于我试图删除的行的顺序。我按升序排序,死锁消失了。所以,是间隙锁锁定了整个表。@vadimbaev这里没有间隙锁的初始问题的示例是什么?