最近看了丁奇写得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或者本人理解不足,发现总是锁多了部分内容,比如:
-------如果不命中数据,不管开闭区间,不仅有间隙锁,连同下一个数据行也有行锁。
-------如果命中数据,如果是开区间,则该数据行也有行锁。
-------如果命中数据,如果是闭区间,则连同该数据行下一个间隙也有间隙锁,同时对应的数据行下一行也有行锁。
具体实验数据见下图:
来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/31441616/viewspace-2644596/,如需转载,请注明出处,否则将追究法律责任。
转载于:http://blog.itpub.net/31441616/viewspace-2644596/