mysql record locks_MYSQL 从Record lock 到 Next-Key Locks 到 GAP_LOCK

大多数人第一次提到锁,可能认为锁可能是针对磁盘上的物理的数据记录,实际上,所有的操作都在内存中完成,锁怎么可能是针对磁盘上的物理数据呢?

在认识到锁都是在内存中产生的后,锁是在什么范围,怎么进行的锁,等等就是进一步需要了解的。

MySQL 中有以下几种锁, Record lock, Gap lock, Next-key lock.

Record lock 是基于索引记录的,也就是他上锁的目标不是记录本身而是索引。那有人就提出异议了,我不建索引,我没有主键,我没有聚簇索引,你奈我何。

你怎么枷锁我,实际上MYSQL的在你不做任何以上的工作时,MYSQL 会无奈的给你一个,A hidden Clustered index, (所以,建MYSQL 不自己建立聚簇索引,属于对MYSQL 耍流氓的行为) ,所以我看见MYSQL不建立主键,并且用UUID的行为我对此是 “极度的遗憾”。

Next-key lock 这个东西默认是在你MYSQL 在 REPEATABLE READ 模式下,防止你幻读的。具体Next-key lock 使用对INDEX 行锁进行GAY LOCKING.

那为什么要特意搞清楚 NEXT-KEY LOCK ,原文档有这样一句话,他说一个 next-key lock 就是一个索引记录锁加上一个GAP 锁, 如果一个session拥有了 S or  X 锁(这里我们先不考虑 IX IS),其他的Session 将不能插入一个新的INDEX RECORD 在间隙锁INDEX 记录之前的位置。

估计说完这句话,more people will be dizziness.

举个例子,我们有以下索引值 id 10,11,13,20

用索引值来表达的  (负无限,10】(10,11】 (11,13】 (13,20】 (20,正无限)

官方文档下面就跟着一句话,NEXT-KEY LOCK 将锁定索引最大值的间隙,In effect, this next-key lock locks only the gap following the        largest index value.  这意味这什么,请打开你的脑洞,这样的操作会对插入有什么影响。

Gap lock  首先 Gap lock只存在于 repeatable read isolation level,在这个level 里面Gap lock才存在。

我们继续上面的那个10,11,13,20的例子,

下面有三个 session 同时运行

Session A

update table set m=m+3 where id =14;

Session B

insert into table (id) values (16);

Session C

insert into table (id) values (21);

则结果 session B 插入数据会失败,因为GAP LOCK 将(13,20】 这一段的索引值都锁上了,不允许在这之间进行数据的插入。

而 Session C 则可以直接插入数据,因为到了20时,值是闭合的。

所以在MYSQL的isolation 选择中,如果你选择了repeatable read, 就意味着你的MYSQL 更要付出更多的心思在语句的设计上,稍不留意,你的MYSQL 就只能不断了报 BLOCK 的错误。

我们在举一个例子

Session A

select * from table where id > 10 and id < 20 for update;

Session B

Insert into table (id) varlues (14);

Session C

insert into table (id) values (21);

这里的结果是  Session B and Session C  都会失败。

原因是next-key lock 范围锁。

使用 repeatable isolation 的MYSQL 会遇到更多的锁和BLOCK的问题,所以这里建议,MYSQL 不要使用 repeatable isolation ,同时唯一索引在MYSQL 中的性能其实也还值得深究,(其实有些大表在处理唯一索引的时候也是如履薄冰,有坑)

我们最后在来一个死锁的案例

session A

begin

select id from table where id = 20 in share mode; (+S)

insert into table (id) values (15)

end

session B

update table set column = column +1 where id = 20;

这样直接session b 会死锁。

这就是repeatable isolation 下的MYSQL NEXT-KEY LOCK & GAP LOCK 会遇到的问题。所以........  我就不多说了

62125ce412a4851229c177e1b913f89c.png

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值