ITPub博客

首页 > 数据库 > MySQL > MySQL 唯一索引范围查询锁下一个记录的理解

MySQL 唯一索引范围查询锁下一个记录的理解

原创 MySQL 作者:aoerqileng 时间:2022-09-22 23:29:24 0 删除 编辑

相信大家研究过锁的同学,都知道在唯一索引的范围查询,会锁下一个记录,在mysql45讲中,作者也提到过,并且认为是个bug,但是官方没有确认,针对这个问题,我也思考了下,下面描述下我的理解,如果不正确,麻烦指正。

mysql> show create table dba_test2\G
*************************** 1. row ***************************
       Table: dba_test2
Create Table: CREATE TABLE `dba_test2` (
  `id` int NOT NULL,
  `age` int DEFAULT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `udx_age` (`age`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1
select * from dba_test2;
+-----+------+
| id  | age  |
+-----+------+
|   1 |   11 |
|   2 |   15 |
|   3 |   20 |
session1;
ysql> select * from dba_test2 where age <=15 for update;
+------+------+
| id   | age  |
+------+------+
|    1 |   11 |
|    2 |   15 |
+------+------+
2 rows in set (0.01 sec)
session2 --被阻塞
 delete from dba_test2 where age=20;


我的理解,如果有这样的事务

begin;

update dba_test2 set age=88 where age=15;

select * from dba_test2 where age <=15 for update;


这样select的时候,看到id=15的记录已经没有了,会向后查找定位记录,找到后加锁,那为什么不向前查找定位记录,向前的话加的锁范围就不对了,导致幻读。所以是向后定位一个记录,如果没有20这个记录,那么就会在最大值上加范围锁。


 

针对这个case,8.0优化了,只是锁了15之前的记录,应该是去查15这条记录是否真实存在了,存在就加15之前的,不存在就向后多加一个范围。

8.0针对最大值的范围,查询没有缩小范围,

select * from dba_test2 where id <=3.,将最大值这个范围锁上了,这个比较奇怪,按理说都是下一个记录锁,处理的方式应该跟上面的方式一样,看来还是没有彻底解决这个问题。


有兴趣学习源码的加群一起学习啊 QQ:                                                                                                                                                                                                                                                                700072075


来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/25719946/viewspace-2915876/ ,如需转载,请注明出处,否则将追究法律责任。

上一篇: MySQL 锁bug?
请登录后发表评论 登录
全部评论
二手知识受害者

注册时间:2011-11-02

  • 博文量
    68
  • 访问量
    47730