求教 MySQL 加锁的一个疑问

2023-04-17 18:27:29 +08:00
 gps32251070

表结构如下:

create table t
(
    id int not null
        primary key,
    c  int null,
    d  int null
);

create index c
    on t (c);
    
insert into t values(0,0,0),(5,5,5),(10,10,10),(15,15,15),(20,20,20),(25,25,25);

mysql 版本:8.0.32 隔离级别 RR

session A session B
begin;
select * from t where id>=15 and id<=20 order by id desc for update ;
insert into t values (22,22,22); //会被阻塞
commit;

请问,id 是主键,为什么 session B 会进入锁等待?按理说唯一索引不会检查区间(20, 25)吧

1833 次点击
所在节点    程序员
23 条回复
SachinBeyond
2023-04-18 19:38:28 +08:00
mysql45 讲 第 21 篇里面提到的第 5 点已经 讲了
https://blog.csdn.net/bohu83/article/details/105344930

一个 bug:唯一索引上的范围查询会访问到不满足条件的第一个值为止。

加锁的基本单位是 next-key lock,
(10,15],(15,20] ,(20,25] 被命中的就是 (10,15],(15,20]

因为这个 id 是主键唯一索引, 这个(15,20] next-key lock 就 i 已经锁住了 id=20 的数据,且在这条数据之后不会有 id=20 数据了(主键唯一性保证),所以理论上( 20 ,25] 可以不用加锁,但是实际上 mysql 会在( 20 ,25]上加锁,又因为 25 这条数据本身没有被命中,所以会退化为( 20 ,25 )的间隙锁。

至于 mysql 为什么会加锁,林哥说这可能是一个 feature
gps32251070
2023-04-18 19:58:23 +08:00
@SachinBeyond 意思是这有可能是个 BUG ?还有,这个左边锁的范围是到 5 ,整体是(5,25)
SachinBeyond
2023-04-18 20:06:23 +08:00
@gps32251070 ( 5 ,10] 这个被锁住我没想到。我试了下确认是被锁住了,整体范围是(5,25)

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/933239

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX