4-MySQL的MVCC

一、背景知识

以下讲解都是在InnoDB的基础上的。
MVCC的意思是multi-version concurrency control,多版本并发控制。官方只是说的多版本multi-version。
MVCC和锁、事务没有必然联系,他们是不同的技术手段,MySQL同时使用了他们,并且产生了耦合。
InnoDB是一个支持多版本的存储引擎。他维护着修改过的行的历史版本信息用以实现事务特性。
MVCC是一种思想,不是MySQL的特有的技术,其他数据库、其他领域都可以使用。

二、整体概述

MySQL大多数事务型存储引擎都不是简单的行级锁,基于并发性能的考虑,他们一般都同时实现了多版本并发控制,不仅是MySQL,Oracle,PostgreSQL等其他数据库都实现了MVCC,但实现的机制各不相同,因为MVCC没有一个统一的实现标准。

由于事务有隔离级别的要求,如RC和RR级别下,未提交的变更不能让其他事务读取,存储多个版本的数据就是一种好的解决方案,比如update数据时,先将目标数据记录一份undolog日志,他代表着当前修改前的数据状态,

三、具体实现

由于事务需要实现隔离级别的语义,也就是说有些修改过的数据不能被看到,换句话说,有些历史数据应该被读取,

MySQL实现MVCC有3个关键手段,第一是行隐藏字段,第二个是undolog(回滚日志),第三个是readview算法,这三个技术方案是实现MVCC的关键。

隐藏字段

InnoDB会在每行数据上添加3个字段:
一个6字节的 DB_TRX_ID 字段,用来标识插入或修改行的最后事务ID。删除也被当做修改对待,通过一个特殊的位来标记是否删除。
一个7字节的 DB_ROLL_PTR 字段,称为回滚指针,回滚指针指向undo log记录,可以理解为上一个版本的行记录。撤销日志用于重建行为被修改前的状态。
一个6字节的 DB_ROW_ID 字段,一个在新增行时单调递增的ID。只有在InnoDB自动生成聚簇索引时,索引才会有row ID。除此之外,DB_ROW_ID不会出现在其他任何索引中。

有了DB_ROLL_PTR这个指针和undo log以后,我们会发现,行记录会成为一个行链,这个链就是行的变化快照线。

undo log

undo log是innodb引擎记录的日志,是用来作为回滚用的。

readview

readview实际上应该是一段算法,他会计算出正在被其他事务访问的数据以及没有被其他事务访问的数据对当前事务可见性。

何时创建readview?

在RC隔离级别下,每一个select语句都会去生成一个readview,在RR隔离级别下,会在事务第一个select时生成一个readview,这个事务结束前都会使用这个readview。readview一旦生成,里面的数据不会发生变化,除非重新生成readview。readview不是在事务开启时创建,而是和select语句相关,因为select就是read。

读取规则

readview主要包括当前活跃事务(已经开启还没提交的事务)id列表trx_list(生成了就不变,除非重新生成),low_limit_id活跃事务ID列表中最大的ID,up_limit_id活跃事务ID列表中最小的ID,这里的low limit id为甚么是最大的呢?low limit是下限的意思,可能作者当时认为数据是从上往下依次递增,所以下限low limit就成了最大值,up limit上限就成立最小值。源码的解释是:

trx_id_t low_limit_id; // The read should not see any transaction with trx id >= this value. In other words, this is the "high water mark".
trx_id_t up_limit_id; // The read should see all trx ids which are strictly smaller (<) than this value. In other words, this is the "low water mark". 

low_limit_id是生成readview时系统中最大的事务ID,up_limit_id是活跃事务列表中最小的事务ID,虽然他俩名字对称,但是语义可不对称。小于up_limit_id的事务ID说明都是已经提交了的事务,大于low_limit_id的事务ID说明都是生成readview之后开启的事务。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值