MySQL 唯一索引範圍查詢鎖下一個記錄的理解

aoerqileng發表於2022-09-22

相信大家研究過鎖的同學,都知道在唯一索引的範圍查詢,會鎖下一個記錄,在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部落格 ” ,連結:http://blog.itpub.net/25719946/viewspace-2915876/,如需轉載,請註明出處,否則將追究法律責任。

相關文章