我在MySql 5.7中遇到了一个问题,当我使用FOR UPDATE选择14行或更多行时,整个表都会被锁定。即使我通过主键选择它们(因此,它是索引的和唯一的)。从字面上看,它是这样的。当我运行此查询时:
select * from mytable
where id in (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13)
for update;一切正常,只有选定的行会被锁定。但是这个查询:
select * from mytable
where id in (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14)
for update;锁定整个表。我不能更新任何其他条目,也不能插入新行。表已锁定。is可以是不同的,重要的是它们的编号(14或更多)。我试着用谷歌搜索它,但什么也没找到。
对于行锁(13行)是否有一些严格的MySql (我们使用5.7版)限制,如果您选择更多行,则会应用表锁?它能以某种方式改变吗?或者这只是我们的具体问题,我们需要更深入地挖掘?
发布于 2021-09-30 19:52:07
看起来没人知道真正的原因。好吧,然后我可以发布一个我们最终达成的解决方案。我们使用临时表,它只包含一个列id,其中我们插入了所有需要的it,然后将其与表连接起来,而不是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;这样,一切都很顺利,无论我们传递多少个ids,都只锁定指定的行。不过,也有一些问题。
首先,如果我们使用engine=memory,由于某些原因,这个技巧不起作用。此外,如果我们使用select而不是values将值插入到临时表中,那么进一步的select for update仍然会在一定数量的ids处锁定整个表。但在后一种情况下,可以通过在插入后立即调用optimize table tmp;来解决问题(当我们使用engine=memory时,它仍然没有帮助)。
所以,就是这样。希望这能帮助到一些人。
https://stackoverflow.com/questions/69011099
复制相似问题