MVCC的实现原理
-
- 1.前期准备
-
- 1.2.隐式字段
- [1.3.undo log日志](#1.3.undo log日志)
- 1.4.readView
- 2.MVCC的实现流程
-
- [2.1.R C(读已提交---隔离级别)](#2.1.R C(读已提交---隔离级别))
- [2.2.R R(可重复读---隔离级别)](#2.2.R R(可重复读---隔离级别))
- 3.面试题---->事务中的隔离性是如何保证的呢?(你解释一下MVCC)
1.前期准备
- 解释一下MVCC
全称 Multi-Version Concurrency Control,
多版本并发控制
。指维护一个数据的多个版本
,使得读写操作没有冲突
例如下图:事务5查询的是哪个事务版本的记录?
MVCC的具体实现,主要依赖于数据库记录中的隐式字段
、undo log日志
、readView。
1.2.隐式字段
含义:每存储一行数据,除了自定义的字段外,还有数据库隐式定义
的 DB_TRX_ID, DB_ROLL_PTR, DB_ROW_ID 等字段
- DB_TRX_ID: 最近修改
事务ID
- DB_ROLL_PTR:
回滚指针
,指向这条记录的上一个版本,用于配合undo log,指向上一个版本。 - DB_ROW_ID:
隐藏主键
,如果表结构没有指定主键,将会生成该隐藏字段。
1.3.undo log日志
含义:回滚日志,在insert、update、delete的时候产生的便于数据回滚的日志。
当
insert
的时候,产生的undo log日志只在回滚时需要
,在事务提交后,可被立即删除。
而update、delete的时候,产生的undo log日志不仅在回滚时需要,
mvcc版本访问也需要,不会立即被删除。
并且在多个事务同时操作同一行数据时,会产生undo log版本链
:(如果是insert操作,只要事务没有回滚,那么会直接删除此条undo log日志)
- 例如在
事务2
进行修改数据时,新数据的回滚指针会指向操作前的undo log版本数据。
- 在事务3修改数据时,新数据的回滚指针会指向操作前的undo log版本数据
以此类推,不同事务或相同事务对同一条记录进行修改,会导致该记录的undolog生成一条记录版本链表
,链表的头部是最新的旧记录
,链表尾部是最早的旧记录
。
1.4.readView
首先先了解什么是当前读和快照读
ReadView(读视图
)是 快照读 SQL执行时MVCC提取数据的依据
,记录并维护系统当前活跃的事务(未提交的)id。
ReadView中包含了四个核心字段:
其中在事务读取数据
的时候,都会根据生成的readView
然后依据版本链访问规则来读取数据
重点:
不同的隔离级别,生成ReadView的时机不同:
READ COMMITTED(读已提交) :在事务中每一次执行快照读时生成ReadView。
REPEATABLE READ(可重复度):仅在事务中第一次执行快照读时生成ReadView
,后续复用
该ReadView。
2.MVCC的实现流程
2.1.R C(读已提交---隔离级别)
RC隔离级别下,在事务中每一次执行快照读时生成ReadView。
同样还是之前的例子:
- 第一次查询id为30的记录
此时生成readview视图,根据视图数据和版本链访问规则,只能访问事务2提交后的数据(也就是事务2提交后记录的undo log)
- 第一次查询id为30的记录
此时又会生成readview视图,根据视图数据和版本链访问规则,只能访问事务3提交后的数据(也就是事务3提交后记录的undo log版本)
2.2.R R(可重复读---隔离级别)
RR隔离级别下,仅在事务中第一次执行快照读时生成ReadView
,后续复用该ReadView。
3.面试题---->事务中的隔离性是如何保证的呢?(你解释一下MVCC)
素材来自:黑马程序员