非唯一索引加锁规则实操
主要是看了小林coding发现对于非唯一索引的情况下跟正常的思路不大一样,特此实验一下
前要知识#
select * from performance_schema.data_locks;
用来查询锁的情况
lock_data
表示锁住的数据,第一个是二级索引的数据,第二个是主键索引的数据
lock_mode
表示 IX = 意向锁 X = next-key lock ….
lock_type
表示 行级锁还是表锁
非唯一索引范围查询#
环境配置#
1 | CREATE TABLE test ( |
记录存在#
大于
1
2
3
4
5
6
7START TRANSACTION;
SELECT * FROM test WHERE age > 25 FOR UPDATE;
commit ;
select * from performance_schema.data_locks;LOCK_TYPE lock_mode lock_status lock_data table IX GRANTED null record x GRANTED supremum pseudo-record record x GRANTED 30, 3 record x GRANTED 40, 7 record X,REC_NOT_GAP GRANTED 3 record X,REC_NOT_GAP GRANTED 7 大于等于
1
2
3
4
5
6
7START TRANSACTION;
SELECT * FROM test WHERE age >= 25 FOR UPDATE;
commit ;
select * from performance_schema.data_locks;lock_type lock_mode lock_status lock_data table IX GRANTED null record X GRANTED supremum pseudo-record record X GRANTED 25, 1 record X GRANTED 30, 3 record X GRANTED 40, 7 record X,REC_NOT_GAP GRANTED 1 record X,REC_NOT_GAP GRANTED 3 record X,REC_NOT_GAP GRANTED 7 小于
1
2
3
4
5
6
7START TRANSACTION;
SELECT * FROM test WHERE age < 25 FOR UPDATE;
commit ;
select * from performance_schema.data_locks;lock_type lock_mode lock_status lock_data TABLE IX GRANTED null record X GRANTED 22, 5 record X GRANTED 25, 1 record X,REC_NOT_GAP GRANTED 5 小于等于
1
2
3
4
5
6
7START TRANSACTION;
SELECT * FROM test WHERE age <= 25 FOR UPDATE;
commit ;
select * from performance_schema.data_locks;lock_type lock_mode lock_status lock_data TABLE IX GRANTED null record X GRANTED 22, 5 record X GRANTED 25, 1 record X GRANTED 30, 3 record X,REC_NOT_GAP GRANTED 1 record X,REC_NOT_GAP GRANTED 5
记录不存在#
大于
1
2
3
4
5START TRANSACTION;
SELECT * FROM test WHERE age > 28 FOR UPDATE;
commit ;lock_type lock_mode lock_status lock_data TABLE IX GRANTED null record X GRANTED supremum pseudo-record record X GRANTED 30, 3 record X GRANTED 40, 7 record X,REC_NOT_GAP GRANTED 3 record X,REC_NOT_GAP GRANTED 7 大于等于
1
2
3
4
5START TRANSACTION;
SELECT * FROM test WHERE age >= 28 FOR UPDATE;
commit ;lock_type lock_mode lock_status lock_data TABLE IX GRANTED null record X GRANTED supremum pseudo-record record X GRANTED 30, 3 record X GRANTED 40, 7 record X,REC_NOT_GAP GRANTED 3 record X,REC_NOT_GAP GRANTED 7 小于
1
2
3
4
5
6
7START TRANSACTION;
SELECT * FROM test WHERE age < 28 FOR UPDATE;
commit ;
select * from performance_schema.data_locks;lock_type lock_mode lock_status lock_data TABLE IX GRANTED null record X GRANTED 22, 5 record X GRANTED 25, 1 record X GRANTED 30, 3 record X,REC_NOT_GAP GRANTED 1 record X,REC_NOT_GAP GRANTED 5 小于等于
1
2
3
4
5
6
7START TRANSACTION;
SELECT * FROM test WHERE age <= 28 FOR UPDATE;
commit ;
select * from performance_schema.data_locks;lock_type lock_mode lock_status lock_data TABLE IX GRANTED null record X GRANTED 22, 5 record X GRANTED 25, 1 record X GRANTED 30, 3 record X,REC_NOT_GAP GRANTED 1 record X,REC_NOT_GAP GRANTED 5
结论#
当非唯一索引范围查询时,next-key lock 不会退化成 record lock 和 gap lock
一般来说他会锁住的范围会延伸到第一个不符合要求的记录(等于情况下找到了数据其实不算不符合要求的数据)
非唯一索引等值查询#
环境准备#
1 | CREATE TABLE test ( |
记录存在#
1 | START TRANSACTION; |
lock_type | lock_mode | lock_status | lock_data |
---|---|---|---|
TABLE | IX | GRANTED | null |
record | X,GAP | GRANTED | 30,3 |
record | X | GRANTED | 25, 1 |
record | X,REC_NOT_GAP | GRANTED | 1 |
记录不存在#
1 | START TRANSACTION; |
lock_type | lock_mode | lock_status | lock_data |
---|---|---|---|
TABLE | IX | GRANTED | null |
record | X,GAP | GRANTED | 30,3 |
总结#
没什么好总结的,这个很好理解…..
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Echin の 博客!