MVCC、Next-Key机制详解

本文详细介绍了MVCC(多版本并发控制)和Next-Key机制,它们在InnoDB存储引擎的可重复读隔离级别下用于解决幻读问题。MVCC提供快照读,允许读取历史版本而不阻塞写操作,而Next-Key锁通过行锁和范围锁防止幻读。当前读会加锁并使用Next-Key锁来确保数据一致性。文章讨论了当前读、快照读下的幻读问题及其解决方案,以及MVCC在不同情况下的效果。
摘要由CSDN通过智能技术生成

1、MVCC 与 Next-Key

  • MVCC不加锁,并发性高,读取到的不一定是实时数据

  • Next-Key需要加锁,获取到的是实时数据

  • InnoDB存储引擎RR 级别(可重复读隔离级别) 下通过 MVCCNext-key Lock 来解决幻读问题:

  • 在可重复读隔离级别下

    • “当前读”读取到的是数据库中最新数据
    • “快照读”读取到的是第一次建立ReadView时可见的数据(不一定是实时数据)
  • 在可重复读事务隔离级别下,默认的查询语句是快照读,MVCC只是利用历史数据,在部分场景下规避了幻读,而要完全解决幻读,需要手动加锁将快照读调整为当前读(mysql不会自动加锁),即使用Next-Key来完全解决幻读

参考:https://blog.csdn.net/qq_27037443/article/details/94390952

在快照读下,即使读取的记录已被其它事务加上 X 锁,这时记录也是可以被读取的,即读取的快照数据。在 Repeatable Read 下 MVCC 解决了快照读下存在的幻读问题,只能读取到第一次查询之前所插入的数据(根据 Read View 判断数据可见性,Read View 在第一次查询时生成)。
在当前读下 ,每次读取的都是最新数据。这时如果两次查询中间有其它事务插入数据,就会产生幻读。所以, InnoDB 在实现Repeatable Read 时,如果执行的是当前读,则会对读取的记录使用 Next-key Lock ,来防止其它事务在间隙间插入数据


2、当前读、快照读

2.1 当前读(current read)

2.1.1 定义

当前读获得数据的最新版本当前读会对读取到的记录加锁(除了第一个加共享锁S,其他都是互斥锁X)

select... lock in share mode(S锁):对记录加 S 锁,其它事务也可以加S锁,如果加 x 锁则会被阻塞
select... for update(X锁)update(X锁)insert(X锁)delete(X锁):对记录加 X 锁,且其它事务不能加任何锁

在执行这几个操作时,会读取最新记录,即其它事务提交的数据也可以被查询到。比如要update一条记录,但是在另一个事务中已经delete掉这条数据并且commit了,如果update就会产生冲突,所以在update的时候需要知道最新的数据。

2.1.2 当前读下的幻读问题

当前读下 ,每次读取的都是最新数据,但是,如果两次查询中间有其它事务在间隙插入数据,就会产生幻读(虽然当前读会加锁,但是加的X、S是行锁,可以避免修改某一行的数据,但是对于间隙无能为力)。所以, InnoDB 在实现Repeatable Read 时,如果执行的是当前读,则会对读取的记录使用 Next-key Lock ,来防止其它事务在间隙间插入数据

在当前读下,加Next-Key锁,阻塞其他并发事务,保证其它事务不会修改当前记录,读取到的是记录的最新版本,避免了当前读下的幻读

2.1.3 Next-Key锁解决当前读下的幻读

间隙锁:所谓的Next-Key锁就是一个行锁(record lock)+范围锁(gap lock),只有在Read Repeatable、Serializable隔离级别才有Next-Key锁,其锁定一个范围并且锁定记录本身 。假设id有3,4,5,锁定id>3的数据时,4、5及后面的数字都会被锁定,这个锁一直到事务提交才会释放,若此时不锁定没有的数据,例如当加入了新的数据id=6,就会出现幻读,因此,间隙锁可以避免幻读。

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

    请填写红包祝福语或标题

    红包个数最小为10个

    红包金额最低5元

    当前余额3.43前往充值 >
    需支付:10.00
    成就一亿技术人!
    领取后你会自动成为博主和红包主的粉丝 规则
    hope_wisdom
    发出的红包

    打赏作者

    还能坚持

    你的鼓励将是我创作的最大动力

    ¥1 ¥2 ¥4 ¥6 ¥10 ¥20
    扫码支付:¥1
    获取中
    扫码支付

    您的余额不足,请更换扫码支付或充值

    打赏作者

    实付
    使用余额支付
    点击重新获取
    扫码支付
    钱包余额 0

    抵扣说明:

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

    余额充值