SQL 必知必会
陈旸
清华大学计算机博士
73338 人已学习
新⼈⾸单¥68
登录后,你可以任选4讲全文学习
课程目录
已完结/共 50 讲
第一章:SQL语法基础篇 (19讲)
SQL 必知必会
15
15
1.0x
00:00/00:00
登录|注册

31丨为什么大部分RDBMS都会支持MVCC?

MVCC在不同隔离级别下的策略差异
MVCC的核心
Next-Key锁
creator_trx_id
up_limit_id
low_limit_id
trx_ids
Undo Log
行记录的隐藏列
事务版本号
当前读
快照读
解决一致性读的问题
降低了死锁的概率
解决读写之间阻塞的问题
总结
InnoDB解决幻读的方式
Read View的工作原理
MVCC在InnoDB中的实现
快照读 vs. 当前读
MVCC的作用
MVCC

该思维导图由 AI 生成,仅供参考

上一篇文章中,我们讲到了锁的划分,以及乐观锁和悲观锁的思想。今天我们就来看下 MVCC,它就是采用乐观锁思想的一种方式。那么它到底有什么用呢?
我们知道事务有 4 个隔离级别,以及可能存在的三种异常问题,如下图所示:
在 MySQL 中,默认的隔离级别是可重复读,可以解决脏读和不可重复读的问题,但不能解决幻读问题。如果我们想要解决幻读问题,就需要采用串行化的方式,也就是将隔离级别提升到最高,但这样一来就会大幅降低数据库的事务并发能力。
有没有一种方式,可以不采用锁机制,而是通过乐观锁的方式来解决不可重复读和幻读问题呢?实际上 MVCC 机制的设计,就是用来解决这个问题的,它可以在大多数情况下替代行级锁,降低系统的开销。
今天的课程主要包括以下几个方面的内容:
MVCC 机制的思想是什么?为什么 RDBMS 会采用 MVCC 机制?
在 InnoDB 中,MVCC 机制是如何实现的 ?
Read View 是如何工作的?

MVCC 是什么,解决了什么问题

MVCC 的英文全称是 Multiversion Concurrency Control,中文翻译过来就是多版本并发控制技术。从名字中也能看出来,MVCC 是通过数据行的多个版本管理来实现数据库的并发控制,简单来说它的思想就是保存数据的历史版本。这样我们就可以通过比较版本号决定数据是否显示出来(具体的规则后面会介绍到),读取数据的时候不需要加锁也可以保证事务的隔离效果。
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

MVCC(Multiversion Concurrency Control)是一种数据库并发控制技术,通过保存数据的历史版本来解决读写之间阻塞、降低死锁概率和解决一致性读的问题。本文重点介绍了InnoDB中MVCC的实现机制,包括Read View的工作原理和InnoDB解决幻读的方式。MVCC通过Undo Log和Read View实现多版本管理和数据可见性判断。在不同隔离级别下,Read View的生成策略不同,实现了不同的隔离效果。文章提出了思考题,引发读者对MVCC机制的深入思考。通过学习本文,读者能够更好地理解MVCC的设计思想和不同隔离级别下的Read View策略差异。MVCC是一种机制,不同数据库的实现方式各有不同,但核心思想是一致的。

仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《SQL 必知必会》
新⼈⾸单¥68
立即购买
登录 后留言

全部留言(50)

  • 最新
  • 精选
  • 许童童
    我来回答一下思考题: 为什么隔离级别为读未提交时,不适用于 MVCC 机制呢? 因为隔离级别是读未提交,所以跟本就不需要版本控制,直接读取最新的数据就好了。 读已提交和可重复读这两个隔离级别的 Read View 策略有何不同? 读已提交每一次Select都会重新查询Read View,保证可以读到其它事务的提交。 可重复读会复用第一次查询到的Read View,不会读到其它事务的提交,加上Next-Key锁的配合,从而避免幻读。

    作者回复: 对的 读未提交不需要版本控制

    2019-08-21
    4
    41
  • DZ
    1. 为什么隔离级别为读未提交时,不适用于 MVCC 机制呢? “读未提交”隔离级别不需要多版本数据。每个事务都读取最新数据,假设事务A把X从0改成1,无论事务A是否提交,事务B读到X为1,如果事务A回滚,事务B再次读X,自然就得到0,根本不需要MVCC帮衬。 2. 读已提交和可重复读这两个隔离级别的 Read View 策略有何不同? “读已提交”时,每次SELECT操作都创建Read View,无论SELECT是否相同,所以可能出现前后两次读到的结果不等,即不可重复读。 “可重复读”时,首次SELECT操作才创建Read View并复用给后续的相同SELECT操作,前后两次读到的结果一定相等,避免了不可重复读。

    作者回复: 对的 分析总结的很好

    2019-08-24
    22
  • 学渣汪在央企打怪升级
    内容量大,看了三遍,感觉有点懂了

    作者回复: 加油 这篇确实有一定难度 ^_^

    2020-03-25
    3
  • Alpha
    Step 4. 如果不符合Read View 规则,就需要从Undo Log中获取历史快照。不太明白这里的"Read View规则"指的是什么?

    作者回复: Read View的规则: 如果 trx_id < 活跃的最小事务 ID(up_limit_id),也就是说这个行记录在这些活跃的事务创建之前就已经提交了,那么这个行记录对该事务是可见的。 如果 trx_id > 活跃的最大事务 ID(low_limit_id),这说明该行记录在这些活跃的事务创建之后才创建,那么这个行记录对当前事务不可见。 如果 up_limit_id < trx_id < low_limit_id,说明该行记录所在的事务 trx_id 在目前 creator_trx_id 这个事务创建的时候,可能还处于活跃的状态,因此我们需要在 trx_ids 集合中进行遍历,如果 trx_id 存在于 trx_ids 集合中,证明这个事务 trx_id 还处于活跃状态,不可见。否则,如果 trx_id 不存在于 trx_ids 集合中,证明事务 trx_id 已经提交了,该行记录可见。

    2019-08-21
    4
    2
  • 编码者
    这块有点难~

    作者回复: 对的 稍微有些难理解,慢慢来

    2019-12-10
    1
  • innovationmech
    看了几遍文章和留言,有点懂了。。。

    作者回复: 加油

    2019-09-16
    1
  • Monday
    以为我看不懂,却原来只是恐惧学习mvcc,仔细看,3、5遍再结合《mysql45讲》的几节,慢慢琢磨品味,终于明白些了。继续学习,比昨天的自己更优秀
    2020-05-29
    13
  • asdf100
    如图所示,trx_ids 为 trx2、trx3、trx5 和 trx8 的集合,活跃的最大事务 ID(low_limit_id)为 trx10,活跃的最小事务 ID(up_limit_id)为 trx4。 没理解这个10和4怎么来的,不是说就2 3 5 8这个活跃事务吗?
    2019-08-21
    3
    6
  • 宋雄斌
    RR 为什么还是会产生幻读呀,后面事务插入的数据它们的事务ID不应该比第一次获取的Read View 的事务ID大吗,那么后面插入的数据不应该看不到的吗??
    2020-07-29
    4
    3
  • 桂冠远航
    老师应该少说了一个细节,就是要对height加索引,因为不加索引的update操作是表锁。
    2020-04-15
    3
收起评论
显示
设置
留言
50
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部