MySql 5.7 中的行锁有限制吗?

Is there a limit for row lock in MySql 5.7?

我在 MySql 5.7 中遇到一个问题,当我 select 14 行或更多行带有 FOR UPDATE 时,整个 table 被锁定。即使我 select 他们通过主键(所以,它是索引和唯一的)。从字面上看,它看起来像这样。当我 运行 这个查询时:

select * from mytable
where id in (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13)
for update;

一切正常,只有 selected 行被锁定。但是这个查询:

select * from mytable
where id in (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14)
for update;

锁定整个 table。我无法更新任何其他条目,也无法插入新行。 table 已锁定。 ID 可以不同,重要的是它们的数量(14 个或更多)。我试图 google 但没有找到任何东西。

是否对行锁(13 行)有一些严格的 MySql(我们使用 5.7 版)限制,如果您 select 多则应用 table 锁?它可以以某种方式改变吗?或者这只是我们的具体问题,我们需要深入挖掘?

看来没有人知道真正的原因。好吧,那么我可以 post 我们最终得出的解决方案。 我们使用了临时 table,它仅包含一列 id,我们在其中插入了所有必需的 ID,然后将其与我们的 table 而不是 IN 子句连接:

CREATE TEMPORARY TABLE if not exists tmp (id int primary key);
truncate tmp;
INSERT INTO tmp VALUES (1), (2), (3), (4), (5), (6), (7), (8), (9), (10), (11), (12), (13), (14), (15);
select t.* from mytable t
join tmp on tmp.id = t.id
for update;

这样一来,无论我们传递多少个 ID,都只会锁定指定的行。不过还是有一些问题。

首先,如果我们使用 engine=memory,由于某种原因,这个技巧不起作用。此外,如果我们使用 select 而不是 values 将值插入到临时 table 中,进一步的 select for update 仍然会在一定数量的 id 处锁定整个 table。但在后一种情况下,可以通过在插入后立即调用 optimize table tmp; 来解决问题(当我们使用 engine=memory 时它仍然没有帮助)。

所以,就是这样。希望这会对某人有所帮助。