Mysql神乎乎的MVCC到底该怎么理解

(1)DB_TRX_ID: 标记更新当前数据记录的transaction id,每处理一个事务,其值自动+1。

(2)DB_ROLL_PTR: 回滚指针,记录了最新一次修改该条记录的undo log,回滚的时候就通过这个指针找到undo log回滚。

(3)DB_ROW_ID: 当数据表没有指定主键时,数据库会自动以这个列来作为主键,生成聚集索引。

假设有如下的一条数据,此时这条数据对应的DB_TRX_ID为10,由于之前没有数据,因此回滚指针对应指向空地址。

在这里插入图片描述

每个事务都有自己的一个id,就像其身份证一样唯一标记该事务。当事务启动的时候,向Innodb存储引擎进行申请。假设此时如果打南边来了个事务A,它的事务id为12,事务A对表中的数据字段count进行修改,修改后该条数据对应的事务id为12,同时回滚指针指向实际的undo log回滚日志的地址。

在这里插入图片描述

此时打北边又来了个事务B,它的事务id为20,事务B将表中的数据字段count修改为21,对应数据的事务id变为20,回滚指针指向上一条undo log信息。如下图所示:

在这里插入图片描述

如果一直有事务进行数据的修改,那么就会形成一条由回滚指针串联的undo log多版本链条。

二、MVCC如何保证事务隔离


阐述完了undo log多版本链条原理,我们知道当一个事务A(事务id=12)更新数据后,当前数据的事务id变为12,同时回滚指针指向undo log数据。每次进行数据更新后,事务id就是修改数据的事务id,同时回滚指针指向回滚数据,最终形成undo log链。但是仅仅依靠undo log多版本链好像并不能实现事务并发执行时的相互隔离,因此我们需要一种机制可以利用undo log多版本链来实现事务隔离。这个机制就是ReadView

Mysql执行事务的时候,会生成一个ReadView,其中会包含以下重要信息:

(1)m_ids:mysql中未提交的事务id集合;

(2)min_trx_id:集合中最小的事务id;

(3)max_trx_idmysql下一个要生成的事务id,也就是事务id集合中最大的事务id加1;

(4)当前需要执行的事务id;

下面我们来说说Mysql的RR(Repeatable Read )隔离级别即可重复读,读取数据的事务,无论读多少次都是和第一次读取数据获得的值时一样的。我们一起来看下可重复读是如何通过MVCC实现的。 假设现在有事务A以及事务B两个事务,A事务需要读取数据,B事务需要修改数据。

在这里插入图片描述

当事务A需要读取数据时,开启ReadView。由于此时数据库活跃的事务为事务A以及事务B,那么对应的ReadViewm_ids={12,34},min_trx_id=12,max_trx_id=35,当前需要执行的事务id为12。此时事务A读取数据时,先判断当前的事务id为12,而数据中的事务id为11,小于当前事务A的id。说明当前读取的数据是在事务A开启之前提交的,因此可以正常进行数据读取。

在这里插入图片描述

如果此时事务B进行了数据修改,修改count为29。而事务A再次进行数据读取时,继续进行判断,发现当前数据对应的事务id为34比当前的查询事务要大,但是小于max_trx_id,同时在m_ids中。说明该事务id对应的事务和事务A属于并发执行事务,因此不能进行数据读取。则根据undo log版本链,往上寻找undo log信息。如果找到的事务id小于当前读取数据的id则证明此时的数据是在当前开启查询事务之前提交的,因此可以进行数据的查询。

在这里插入图片描述

那么另外一个问题又来了,RC级别又是如何实现的呢?所谓RC级别,就是当别人的事务提交后,你就可以读取到别人修改后的值。因此会发生不可重复读问题。当设置为事务级别为RC时,它每次发起数据查询(set session transaction isolation level read committed;)后,每次进行数据查询都会新开启一个新的ReadView

假设当前事务中活跃着两个事务,他们的事务id分别是12、34。此时事务id为34的事务更新了数据。此时数据更新为29。同时数据对应的事务id更新为34,同时回滚指针指向上一条数据。若此时事务id为15的事务进行数据查询,此时开启readview,进行检查,发现此时的数据中对应的事务id在活跃事务id中,说明是和查询事务差不多时机执行的,但是此时的事务还未提交。因此此时的数据不可以读,所以顺着undolog版本链条读取上一次的数据。同时进行判断。

如果事务B进行了提交,那么事务A再次进行数据查询的时候,会新开启一个ReadView,我们暂且称之为ReadViewA1,由于此时的事务B已经提交,所以ReadViewA1中对应的活跃列表中只有事务A对应的事务id为12。此时发现事务已提交,不再活跃事务列表中,因此可以进行数据读取。

在这里插入图片描述

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

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

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

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

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

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

img

最后

经过日积月累, 以下是小编归纳整理的深入了解Java虚拟机文档,希望可以帮助大家过关斩将顺利通过面试。
由于整个文档比较全面,内容比较多,篇幅不允许,下面以截图方式展示 。







由于篇幅限制,文档的详解资料太全面,细节内容太多,所以只把部分知识点截图出来粗略的介绍,每个小节点里面都有更细化的内容!
《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!
《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!

  • 24
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值