mysql next-key lock的理解

来源:这里教程网 时间:2026-03-01 12:02:40 作者:

最近看了丁奇写得mysql 45讲中关于锁的文章,有些不理解,做了如下实验。 https://www.cnblogs.com/a-phper/p/10313940.html 如下是示例表:     CREATE TABLE `t` (     `id` int(11) NOT NULL,     `c` int(11) DEFAULT NULL,     `d` int(11) DEFAULT NULL,     PRIMARY KEY (`id`),     KEY `c` (`c`)     ) ENGINE=InnoDB;     insert into t values(0,0,0),(5,5,5),     (10,10,10),(15,15,15),(20,20,20),(25,25,25); 一共有6行数据,包含id唯一索引,c非唯一索引。 等值查询测试案例 --------session1: ----------------begin; ----------------select * from t where id=5 for update; --------session2: ----------------insert into t values (3,3,3); ----------------insert into t values (8,8,8); ----------------update t set d=d+1 where id=5; 范围查询测试案例 --------session1: ----------------begin; ----------------select * from t where id >=5 and id <= 10 for update; --------session2: ----------------insert into t values (3,3,3); ----------------insert into t values (8,8,8); ----------------insert into t values (11,11,11); ----------------update t set d=d+1 where id=0; ----------------update t set d=d+1 where id=5; ----------------update t set d=d+1 where id=10; ----------------update t set d=d+1 where id=15; 如下是【mysql社区版 单实例 5.7.25】的【可重复读隔离级别】的实验结论: 1、对于等值查询 --------针对唯一索引 ----------------如果命中数据行,则只有行锁。 ----------------如果不命中数据行,则锁住对应的间隙。 --------针对非唯一索引 ----------------如果命中数据行,则锁住数据行前后的两个间隙。 ----------------如果不命中数据行,则锁住对应的间隙。 2、对于范围查询 --------针对唯一索引 ----------------针对左边的区间 ------------------------如果命中数据行,则锁左边的范围跟数据行一致。 ------------------------如果不命中数据行,则锁左边的范围包含数据行所在的间隙。 ----------------针对右边的区间 ------------------------如果命中数据行 --------------------------------如果是开区间,则锁右边的范围包含对应数据行。(bug?) --------------------------------如果是闭区间,则锁右边的范围包含到对应数据行的下一条记录。(bug?) ------------------------如果不命中数据行,不管是开区间还是闭区间,锁右边的范围都包含到相关间隙的下一数据行。(bug?) --------针对非唯一索引 ----------------针对左边的区间 ------------------------如果命中数据行 --------------------------------如果是闭区间,则锁左边范围还需要包含上一个间隙。 --------------------------------如果是开区间,则锁左边范围与左边区间一致。 ------------------------如果不命中数据行,不管是开区间还是闭区间,则锁左边范围需要包含数据行所在的间隙。 ----------------针对右边的区间 ------------------------如果命中数据行 --------------------------------如果是开区间,则锁右边的范围包含对应数据行。(bug?) --------------------------------如果是闭区间,则锁右边的范围包含到对应数据行的下一条记录。(bug?) ------------------------如果不命中数据行,不管是开区间还是闭区间,锁右边的范围都包含到相关间隙的下一数据行。(bug?) 综上所述,大部分均能理解,但是对于范围查询的右边区域,不知道是否mysql bug或者本人理解不足,发现总是锁多了部分内容,比如: -------如果不命中数据,不管开闭区间,不仅有间隙锁,连同下一个数据行也有行锁。 -------如果命中数据,如果是开区间,则该数据行也有行锁。 -------如果命中数据,如果是闭区间,则连同该数据行下一个间隙也有间隙锁,同时对应的数据行下一行也有行锁。 具体实验数据见下图:

相关推荐