大多数人第一次提到锁,可能认为锁可能是针对磁盘上的物理的数据记录,实际上,所有的操作都在内存中完成,锁怎么可能是针对磁盘上的物理数据呢?
在认识到锁都是在内存中产生的后,锁是在什么范围,怎么进行的锁,等等就是进一步需要了解的。
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 会遇到的问题。所以........ 我就不多说了