MySQL间隙锁、Next-Key Lock主要知识点

总体来说,就是MySQL innoDB引擎要在RR隔离级别之下解决幻读的问题,所以引入了间隙锁。

在进行当前读的情况下,对读出的数据的附近的一整个范围(“间隙”)进行加锁,保证满足查询条件的记录不能被插入。

1、幻读与innoDB的隔离级别(为什么会出现间隙锁这个概念)

根据 ISO/ANSI SQL92 所定义的标准,四级隔离级别中,只有在可串行化的级别之下,才可以防止幻读的出现。

隔离级别

所谓幻读,指的是事务A执行过程中,由于事务B并发插入了一条新数据,事务A两次读数据的内容不一样,出现了“虚幻”的新纪录(phantom,幽灵)。

但实际上各厂商的数据库产品并没有严格遵守SQL92标准,比如Oracle只有 RC 和 Serializable 两级隔离级别。

MySQL的innoDB引擎虽然拥有标准的四级隔离级别(其实也是MVCC等手段模拟出来的),不过它有一点显著的不同,就是在 RR 级别下面已经可以防止幻读的发生。

  • 在快照读(snapshot read)的情况下,MySQL通过MVCC(多版本并发控制)来避免幻读。

    快照读,读取的是记录的可见版本 (有可能是历史版本),不用加锁。主要应用于无需加锁的普通查询(select)操作。

  • 在当前读(current read)的情况下,MySQL通过next-key lock来避免幻读。

    当前读,读取的是记录的最新版本,并且会对当前记录加锁,防止其他事务发修改这条记录。加行共享锁(SELECT ... LOCK IN SHARE MODE )、加行排他锁(SELECT ... FOR UPDATE / INSERT / UPDATE / DELETE)的操作都会用到当前度。行锁可参看 MySQL行锁

下面主要说明跟间隙锁相关的当前读。

2、innoDB的间隙锁/Next-Key Lock

2-1、明确前提条件
  • innoDB的间隙锁只存在于 RR 隔离级别

所以希望禁用间隙锁,提升系统性能的时候,可以考虑将隔离级别降为 RC。

2-2、间隙锁/Next-Key Lock

间隙锁在innoDB中的唯一作用就是在一定的“间隙”内防止其他事务的插入操作,以此防止幻读的发生:

  • 防止间隙内有新数据被插入。
  • 防止已存在的数据,更新成间隙内的数据。

innoDB支持三种行锁定方式:

  • 行锁(Record Lock):锁直接加在索引记录上面(无索引项时演变成表锁)。

  • 间隙锁(Gap Lock):锁定索引记录间隙,确保索引记录的间隙不变。间隙锁是针对事务隔离级别为可重复读或以上级别的。

  • Next-Key Lock :行锁和间隙锁组合起来就是 Next-Key Lock。

innoDB默认的隔离级别是可重复读(Repeatable Read),并且会以Next-Key Lock的方式对数据行进行加锁。Next-Key Lock是行锁和间隙锁的组合,当InnoDB扫描索引记录的时候,会首先对索引记录加上行锁(Record Lock),再对索引记录两边的间隙加上间隙锁(Gap Lock)。加上间隙锁之后,其他事务就不能在这个间隙修改或者插入记录。

当查询的索引含有唯一属性(唯一索引,主键索引)时,Innodb存储引擎会对next-key lock进行优化,将其降为record lock,即仅锁住索引本身,而不是范围。

2-3、何时使用行锁,何时产生间隙锁

对上一节的最后一句做个扩展说明。

  1. 只使用唯一索引查询,并且只锁定一条记录时,innoDB会使用行锁。
  2. 只使用唯一索引查询,但是检索条件是范围检索,或者是唯一检索然而检索结果不存在(试图锁住不存在的数据)时,会产生 Next-Key Lock。
  3. 使用普通索引检索时,不管是何种查询,只要加锁,都会产生间隙锁。
  4. 同时使用唯一索引和普通索引时,由于数据行是优先根据普通索引排序,再根据唯一索引排序,所以也会产生间隙锁。
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 1. mysql锁知多少 我们进行insert,update,delete,select会加锁吗,如果加锁,加锁步...
    liwsh阅读 5,029评论 0 4
  • 一、概述 数据库锁定机制简单来说,就是数据库为了保证数据的一致性,而使各种共享资源在被并发访问变得有序所设计的一种...
    不变甄心阅读 2,743评论 0 3
  • 前言 数据库锁定机制是数据库为了保证数据的一致性而使各种共享资源在并发访问时变的有序的一种规则。MySQL数据库的...
    Justlearn阅读 1,689评论 0 4
  • 有时候,放下自己曾经倾尽心血的人,或者事,不是很容易!就像自己含辛茹苦养大的孩子突然夭折一般!抑或像自己努力培养的...
    angel妖姐阅读 339评论 0 0
  • [ 转自 ]基于区块链的智能合约安全(二)——已知的漏洞和陷阱博客新地址 私钥泄露 使用不安全的私钥确实是一个常见...
    CapybaraJ阅读 1,430评论 0 0