当前位置:网站首页>MySQL select加锁分析
MySQL select加锁分析
2022-08-04 15:18:00 【知知之之】
InnoDB行锁是通过给索引上的索引项加锁来实现的,这一点MySQL与Oracle不同,后者是通过在数据块中对相应数据行加锁来实现的。 InnoDB这种行锁实现特点意味着:只有通过索引条件检索数据,InnoDB才使用行级锁,否则,InnoDB将使用表锁!
下面讨论是基于InnoDB引擎、事务隔离级别:可重复读和串行化
表数据如下,pId为主键索引
| pId(int) | name(varchar) | num(int) |
|---|---|---|
| 1 | aaa | 100 |
| 2 | bbb | 200 |
| 7 | ccc | 200 |
RR/Serializable+条件列非索引
RR级别需要多考虑的就是gap lock,他的加锁特征在于,无论你怎么查都是锁全表。如下所示
接下来分析开始
(1)select * from table where num = 200
在RR级别下,不加任何锁,是快照读。
在Serializable级别下,在pId = 1,2,3,7(全表所有记录)的聚簇索引上加S锁。并且在
聚簇索引的所有间隙(-∞,1)(1,2)(2,3)(3,7)(7,+∞)加gap lock
(2)select * from table where num > 200
在RR级别下,不加任何锁,是快照读。
在Serializable级别下,在pId = 1,2,3,7(全表所有记录)的聚簇索引上加S锁。并且在
聚簇索引的所有间隙(-∞,1)(1,2)(2,3)(3,7)(7,+∞)加gap lock
(3)select * from table where num = 200 lock in share mode
在pId = 1,2,3,7(全表所有记录)的聚簇索引上加S锁。并且在
聚簇索引的所有间隙(-∞,1)(1,2)(2,3)(3,7)(7,+∞)加gap lock
(4)select * from table where num > 200 lock in share mode
在pId = 1,2,3,7(全表所有记录)的聚簇索引上加S锁。并且在
聚簇索引的所有间隙(-∞,1)(1,2)(2,3)(3,7)(7,+∞)加gap lock
(5)select * from table where num = 200 for update
在pId = 1,2,3,7(全表所有记录)的聚簇索引上加X锁。并且在
聚簇索引的所有间隙(-∞,1)(1,2)(2,3)(3,7)(7,+∞)加gap lock
(6)select * from table where num > 200 for update
在pId = 1,2,3,7(全表所有记录)的聚簇索引上加X锁。并且在
聚簇索引的所有间隙(-∞,1)(1,2)(2,3)(3,7)(7,+∞)加gap lock
RR/Serializable+条件列是聚簇索引
该情况的加锁特征在于,如果where后的条件为精确查询(=的情况),那么只存在record lock。如果where后的条件为范围查询(>或<的情况),那么存在的是record lock+gap lock。
(1)select * from table where pId = 2
在RR级别下,不加任何锁,是快照读。
在Serializable级别下,是当前读,在pId=2的聚簇索引上加S锁,不存在gap lock。
(2)select * from table where pId > 2
在RR级别下,不加任何锁,是快照读。
在Serializable级别下,是当前读,在pId=3,7的聚簇索引上加S锁。在(2,3)(3,7)(7,+∞)加上gap lock
(3)select * from table where pId = 2 lock in share mode
是当前读,在pId=2的聚簇索引上加S锁,不存在gap lock。
(4)select * from table where pId > 2 lock in share mode
是当前读,在pId=3,7的聚簇索引上加S锁。在(2,3)(3,7)(7,+∞)加上gap lock
(5)select * from table where pId = 2 for update
是当前读,在pId=2的聚簇索引上加X锁。
(6)select * from table where pId > 2 for update
在pId=3,7的聚簇索引上加X锁。在(2,3)(3,7)(7,+∞)加上gap lock
(7)select * from table where pId = 6 [lock in share mode|for update]
注意了,pId=6是不存在的列,这种情况会在(3,7)上加gap lock。
(8)select * from table where pId > 18 [lock in share mode|for update]
注意了,pId>18,查询结果是空的。在这种情况下,是在(7,+∞)上加gap lock。
RR/Serializable+条件列是非聚簇索引
这里非聚簇索引,需要区分是否为唯一索引。因为如果是非唯一索引,间隙锁的加锁方式是有区别的。
先说一下,唯一索引的情况。如果是唯一索引,情况和RR/Serializable+条件列是聚簇索引类似,唯一有区别的是:这个时候有两棵索引树,加锁是加在对应的非聚簇索引树和聚簇索引树上!大家可以自行推敲!
下面说一下,非聚簇索引是非唯一索引的情况,他和唯一索引的区别就是通过索引进行精确查询以后,不仅存在record lock,还存在gap lock。而通过唯一索引进行精确查询后,只存在record lock,不存在gap lock。老规矩在num列建立非唯一索引
(1)select * from table where num = 200
在RR级别下,不加任何锁,是快照读。
在Serializable级别下,是当前读,在pId=2,7的聚簇索引上加S锁,在num=200的非聚集索引上加S锁,在(100,200)(200,300)加上gap lock。
(2)select * from table where num > 200
在RR级别下,不加任何锁,是快照读。
在Serializable级别下,是当前读,在pId=3的聚簇索引上加S锁,在num=300的非聚集索引上加S锁。在(200,300)(300,+∞)加上gap lock
(3)select * from table where num = 200 lock in share mode
是当前读,在pId=2,7的聚簇索引上加S锁,在num=200的非聚集索引上加S锁,在(100,200)(200,300)加上gap lock。
(4)select * from table where num > 200 lock in share mode
是当前读,在pId=3的聚簇索引上加S锁,在num=300的非聚集索引上加S锁。在(200,300)(300,+∞)加上gap lock。
(5)select * from table where num = 200 for update
是当前读,在pId=2,7的聚簇索引上加S锁,在num=200的非聚集索引上加X锁,在(100,200)(200,300)加上gap lock。
(6)select * from table where num > 200 for update
是当前读,在pId=3的聚簇索引上加S锁,在num=300的非聚集索引上加X锁。在(200,300)(300,+∞)加上gap lock
(7)select * from table where num = 250 [lock in share mode|for update]
注意了,num=250是不存在的列,这种情况会在(200,300)上加gap lock。
(8)select * from table where num > 400 [lock in share mode|for update]
注意了,pId>400,查询结果是空的。在这种情况下,是在(400,+∞)上加gap lock。
边栏推荐
- Basic Introduction for PLSQL
- 微软表示将向内部网络安全专家共享数据 为企业提供更安全保护
- 16. Learn MySQL Regular Expressions
- This week to discuss the user experience: Daedalus Nemo to join Ambire, explore the encryption of the ocean
- 我在羊毛和二手群里报复性消费
- 卖家寄卖流程梳理
- leetcode:253. 至少需要多少间会议室
- 洛谷题解P1028 数的计算
- 2022 Hangzhou Electric Multi-School 4
- leetcode:212. 单词搜索 II
猜你喜欢
随机推荐
leetcode: 253. How many meeting rooms are required at least
leetcode: 255 Verify preorder traversal sequence binary search tree
I love Tanabata hahaha
什么,你告诉我?作用域也分种类?
Hangzhou Electric School Competition (Counter Attack Index)
Redis-哨兵模式
leetcode:215无序数组中找第k大的元素
QT笔记——Q_INVOKABLE了解
LeetCode_模拟_中等_498.对角线遍历
MVCC实现过程
技术分享| 小程序实现音视频通话
IP报文头解析
【Harmony OS】【FAQ】鸿蒙问题合集2
Next -19- 开启fancybox查看图片大图
我在羊毛和二手群里报复性消费
2022杭电多校4
华为云 & 达达,帮有情人“一键送达”
1401 - Web technology 】 【 introduction to graphical Canvas
leetcode:241. 为运算表达式设计优先级
leetcode: 241. Designing precedence for arithmetic expressions








