MySQL 之 MVCC介绍

简介

MVCC (multiversion concurrency control),多版本并发控制,主要是通过在每一行记录中增加三个字段,与 undo log 中相关记录配合使用,同时加上可见性算法,使得各个事务可以在不加锁的情况下能够同时地读取到某行记录上的准确值(这个值对不同的事务而言可能是不同的)。使用 MVCC,在不加锁的情况下也能读取到准确的数据,大大提高了并发效率。

MVCC 更新操作

在数据库表的记录中,每一个记录都会添加三个字段:

  • DB_TRX_ID: 6个字节,表示最近一次修改本记录的事务ID
  • DB_ROLL_PTR : 7 个字节,回滚指针,指向回滚段中的 undo log record,用于找出这个记录的上个修改版本的数据。
  • DB_ROW_ID: 6 个字节,一个单调递增的 ID,确定表中记录的唯一性。

当对某个记录进行更新时,会将当前记录写入 undo log 中,并更新当前记录中 DB_ROLL_PTR 字段值,使其指向刚才的 undo log record,然后更新当前记录相关字段值,同时更新 DB_TRX_ID 字段,记录执行更新操作的事务 ID。简略的更新过程大致如下所示
在这里插入图片描述
简单理解就是:当一个新的事务要更新某一记录时,先把回滚指针指向前一个事务的该记录地址,然后把事务ID递增加1。

查询操作

由上面的更新操作可以得知,数据库表记录始终记录着最新的更新结果,那对于「可重复读」和「读提交」的隔离级别的事务,它是如何保证在开启本事务后,其他事务对记录进行了更新操作,而本事务仍然能够读取到准确的值(不是表记录的最新值,而是历史版本的值)的?

从更新操作中可以得知,通过循环遍历 DB_ROLL_PTR 可以拿到当前记录的历史版本(当然,只是活跃的事务,如果当前记录没有相关事务在操作,则会清理 undo log,就不能拿到历史版本数据了) 。
但是这么多历史版本的数据,究竟哪个版本的数据才是当前事务所要的呢?这时就要判断当前版本的数据是否对当前事务可见了。

在开启事务时,会将当前活跃的事务(已经开启了事务,但是还没有提交)的事务 ID 放在一个活跃事务数组里面,同时记录数组里面最小的事务 ID 为「低水位」,记录当前系统已经创建的事务ID 的最大值加一为「高水位」。这三者组成了一个事务的一致性视图(read-view)。
当事务要查询某个记录的数据时,实际上就是拿该记录的事务ID(包括历史版本的事务ID)和这个一致性视图进行比较,直到某个版本的数据是可见的为止。 其查询过程如下:

  • 读取的记录的事务ID小于低水位,说明这个版本的数据在开启本事务前已经提交,是可见的,直接返回这个数据。
  • 读取的记录的事务ID大于高水位,说明这个版本的数据在开启本事务后提交的,不可见,从记录中取出 DB_ROLL_PTR 指向的记录并读取其事务 ID,开始下一轮的判断。
  • 读取的记录的事务ID介于低水位和高水位中间,此时判断事务ID是否在一致性视图的活跃事务数组中:
    如果不在,说明这个版本的数据在开启本事务前已经提交,是可见的,直接返回这个数据。
    如果在,说明这个版本的数据是由开启事务后的其他活跃事务提交的,对本事务是不可见的,因此需要从记录中取出 DB_ROLL_PTR 指向的记录并读取其事务 ID,开始下一轮的判断。
    其判断过程的流程图大致如下所示
    在这里插入图片描述
    关于判断数据可见性,除了上述用高水位、低水位和事务视图数组结合判断之外,可以简化成以下规则判断:
  • 对于当前事务中的数据,可见。
  • 对于其他事务中的数据:
    如果版本未提交,不可见。
    如果版本已经提交,且是在创建本事务视图后提交的,不可见。
    如果版本已经提交,且是在创建本事务视图前提交的,可见。

其他

「读提交」隔离级别下每次都是读取的最新记录,所以不用 MVCC,也不用创建一致性视图;「串行化」隔离级别,则是用加锁方式来实现并发的,也不用 MVCC ,所以也不用创建一致性视图。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值