MySQL~MVCC多版本并发控制机制实现原理(read view、undo log、实现RC和RR)

本文探讨了MVCC在MySQLInnoDB存储引擎中的应用,如何通过多版本机制和快照读减少读写冲突,提高并发性能,并重点介绍了RC和RR隔离级别的实现原理以及MVCC在解决脏读和不可重复读问题中的作用。
摘要由CSDN通过智能技术生成
  • 当前读和快照读

  • MVCC如何帮助锁实现RC和RR

MVCC


  • MVCC是一种多版本并发控制机制。

  • 大家都应该知道,使用锁和锁协议来实现相应的隔离级别来进行并发控制,味道虽好但因为锁会造成事务阻塞,导致并发性能会受到一定的影响。而多版本并发控制使得对同一行记录做读写的事务之间不用相互阻塞等待(写写还是要阻塞等待,因为事务对数据进行更新时会加上排他锁),提高了事务的并发能力,可以认为MVCC是一种 解决读写阻塞等待的行级锁 。

  • 也就是说在InnoDB中MVCC技术是和行锁机制一起使用的

  • 所谓多版本就是数据库表中每一行数据都可能存在多个版本,对数据库的任何修改的提交都不会直接覆盖之前的数据,而是产生一个新的版本与老版本共存,通过读写数据时读不同的版本来避免加锁阻塞。不同的存储引擎实现的MVCC多少有些差异,这里主要讨论下Mysql的默认存储引擎InnoDB对MVCC的实现原理。MVCC的实现主要依赖于数据库在每个表中添加的三个隐藏字段以及事务在查询时创建的快照(read view)和数据库的撤销日志(Undo log)。

  • MVCC的重要特性:

(1)MVCC只支持RC(读取已提交)和RR(可重复读)隔离级别。

(2)MVCC能帮助锁机制解决脏读、不可重复读问题,不能解决丢失更新问题和幻读问题。

(3)MVCC是用来解决读写操作之间的阻塞问题。使得在并发读写数据库时,可以做到在读操作时不用阻塞写操作,写操作也不用阻塞读操作,提高了数据库并发读写的性能。

如何多版本

  • InnoDB会为每个使用InnoDB存储引擎的表添加三个隐藏字段,用于实现数据多版本和无主键前提下的聚集索引,他们的作用如下:
  1. DB_TRX_ID(6字节): 它是最近一次更新或者插入或者删除该行数据的事务ID(若是删除,则该行有一个删除位更新为已删除。但并不是真正的进行物理删除,当InnoDB丢弃为删除而编写的更新撤消日志记录时,它才会物理删除相应的行及其索引记录。此删除操作称为清除,速度非常快)

  2. DB_ROLL_PTR(7字节): 回滚指针,指向当前记录行的undo log信息(指向该数据的前一个版本数据)

  3. DB_ROW_ID(6字节): 随着新行插入而单调递增的行ID。InnoDB使用聚集索引,数据存储是以聚集索引字段的大小顺序进行存储的,当表没有主键或唯一非空索引时,innodb就会使用这个行ID自动产生聚簇索引。如果表有主键或唯一非空索引,聚簇索引就不会包含这个行ID了。这个DB_ROW_ID跟MVCC关系不大。

Read View

  • read view是一种快照,里面记录了系统中当前活跃事务的ID以及相关信息,主要用途是用来做可见性判断,判断当前事务是否有资格访问该行数据

Undo log

  • Undo log是逻辑日志,操作数据库数据就必回在这个日志文件中进行记录, 其中存储的是老版本数据,当一个事务需要读取记录行时,如果当前记录行不可见,可以通过回滚指针顺着undo log链找到满足其可见性条件的记录行版本。

  • 在InnoDB里,undo log分为如下两类:

①insert undo log : 事务对insert新记录时产生的undo log, 只在事务回滚时需要, 并且在事务提交后就可以立即丢弃。

②update undo log : 事务对记录进行delete和update操作时产生的undo log,不仅在事务回滚时需要,快照读也需要,所以不能轻易删除,只有当数据库所使用的快照中不涉及该日志记录,对应的回滚日志才会被purge线程删除。

Purge线程:上文提到了InnoDB删除一个行记录时,并不是立刻物理删除,而是将该行数据的DB_TRX_ID字段更新为做删除操作的事务ID,并将删除位deleted_bit设置为true(已删除),将其放入update undo log中。为了节省磁盘空间,InnoDB有专门的purge线程来清理deleted_bit为true的记录。purge线程自己也维护了一个read view,如果某个记录的deleted_bit为true,并且DB_TRX_ID相对于purge线程的read view可见,那么这条记录一定是可以被安全清除的。

MVCC实现原理


更新操作实现原理

  • MVCC机制下实现更新还是会用到排他锁,但由于我们读的时候可以通过快照读,读多个版本就好比使用了共享锁,因此可以使得读事务不会因为写事务阻塞。MVCC的优越性在于事务需要读行记录的时候不会因为有事务在更新该行记录而阻塞,事务在写行记录时也不会因为有事务在读数据而阻塞。

  • 更新原理: 假设我现在需要修改行记录A,他们的修改过程如下,

(1)MVCC更新行记录A时会先用排他锁锁住该行记录A;

(2)然后将该行记录复制到update undo log中,生成旧版本行记录B;

(3)使行记录A的回滚指针指向这条旧版本B,再在行记录A中修改 用户需要修改的字段,并将DB_TRX_ID字段更新为更新这条记录的事务ID;

(4)最后提交事务。(用户需要修改的字段指的是业务字段,比如我们要修改name等)

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数Java工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

如果你觉得这些内容对你有帮助,可以扫码获取!!(备注Java获取)

img

结局:总结+分享

看完美团、字节、腾讯这三家的一二三面试问题,是不是感觉问的特别多,可能咱们真的又得开启面试造火箭、工作拧螺丝的模式去准备下一次的面试了。

开篇有提及我可是足足背下了Java互联网工程师面试1000题,多少还是有点用的呢,换汤不换药,不管面试官怎么问你,抓住本质即可!能读到此处的都是真爱

  • Java互联网工程师面试1000题

image.png

而且从上面三家来看,算法与数据结构是必备不可少的呀,因此我建议大家可以去刷刷这本左程云大佬著作的 《程序员代码面试指南 IT名企算法与数据结构题目最优解》,里面近200道真实出现过的经典代码面试题。

  • 程序员代码面试指南–IT名企算法与数据结构题目最优解

image.png

  • 其余像设计模式,建议可以看看下面这4份PDF(已经整理)

image.png

  • 更多的Java面试学习笔记如下,关于面试这一块,我额外细分出Java基础-中级-高级开发的面试+解析,以及调优笔记等等等。。。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

以上所提及的全部Java面试学习的PDF及笔记,如若皆是你所需要的,那么都可发送给你!

《一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码》点击传送门即可获取!
以上所提及的全部Java面试学习的PDF及笔记,如若皆是你所需要的,那么都可发送给你!

《一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码》点击传送门即可获取!

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值