MYSQL隔离性原理——MVCC

表的隐藏字段

表的列包含用户自定义的列和由系统自动创建的隐藏字段。我们介绍3个隐藏字段,不理解也没有关系,理解后面的undo log就懂了:

  • DB_TRX_ID :6 byte,最近修改( 修改/插入 )事务ID,记录创建这条记录/最后一次修改该记录的事务ID
  • DB_ROLL_PTR : 7 byte,回滚指针,指向这条记录的上一个版本(简单理解成,指向历史版本就行,这些数据一般在 undo log 中)
  • DB_ROW_ID : 6 byte,隐含的自增ID(隐藏主键),如果数据表没有主键, InnoDB 会自动以DB_ROW_ID 产生一个聚簇索引

undo log

undo log是一个缓冲区,用来存放记录修改的历史记录。

以下面这个表为例讲解:

当我们插入一条记录后,这个表中的内容实际上是这样的:

|----|------|------------------|-------------|-----|
| id | name | DB_TRX_ID | DB_ROLL_PTR | ... |
| 1 | Tom | 创建当前记录的事务id,假设为1 | null |

如果我们在一个事务中修改这个记录,它的过程是这样的:

先将当前记录做备份,放到undo log中。同时将修改后的记录的DB_ROLL_PTR设置为上一个记录的地址。就这样将记录的每个版本都用回滚指针连起来,形成一个版本控制链 。当我们想要回滚到某个版本时,就可以直接找到。这一个个版本,我们称之为快照。

另外,不需要考虑undo log满的情况。在一个事务commit之后,修改记录的所有版本都会释放。

ReadView

undo log看起来和隔离性没什么关系,其实不然。隔离性是由undo log和readview配合实现的!

先介绍连个两个概念:

当前读:读取最新的记录,就是当前读。增删改,都叫做当前读。

快照读:读取记录的历史版本(一般而言),就叫做快照读。


Readview是一个类,可以记录数据库当前活跃事务的id,以及事务id的分配情况,相当于当前数据库的一个快照。我们简单了解几个类成员:

  • m_ids; //一张列表,用来记录Read View生成时,系统正进行的事务的ID
  • up_limit_id; //记录m_ids列表中事务ID最小的ID,小于这个值的事务id,就说明这个事务已经commit了。
  • low_limit_id; //ReadView生成时刻系统尚未分配的下一个事务ID,也就是目前已出现过的事务ID的最大值+1。大于这个id值的事务,就是在Read View生成后新开始的事务。
  • creator_trx_id //创建该ReadView的事务ID

隔离性的实现

ReadView会在事务进行快照读的时候创建,此时,事务会被分成三类:

对于read uncommitted,这三类事务的记录快照对于当前进行的事务来讲全部可见。

对于read committed和repeatable read,在第一个区间的事务id的记录快照可见;在第二个区间内但是不在m_ids中的事务的记录快照也可见,但是在m_ids中的事务的记录快照不可见;在第三个区间的事务的记录快照不可见。

那么,RC和RR的区别在哪?

对于RC,当前事务每次进行快照读的时候,都会创建ReadView。因此,当并行事务commit后,再进行快照读,这条记录就会变得可见。

对于RR,只在事务第一次进行快照读时创建ReadView,后续不会再创建。因此,不管并行的事务是否commit,都无法看到修改后的记录。

相关推荐
岳麓丹枫0014 分钟前
PG数据库无法接受连接问题分析定位
数据库·postgresql
JdSnE27zv19 分钟前
SQLite内存数据库
数据库·sql·sqlite
SelectDB技术团队20 分钟前
预约发布会|核心产品力首发,如何构建面向 Agent 时代的企业级数据引擎
数据库·数据仓库·人工智能·数据分析·可观测·apache doris·selectdb
2601_9618451526 分钟前
2026四级作文预测题|英语四级写作押题+提纲PDF
java·c语言·数据库·c++·python·pdf·php
计算机安禾28 分钟前
【数据库系统原理】第13篇:现实世界的概念抽象:实体-联系模型向关系模型的转化策略
数据库
JAVA面经实录91738 分钟前
NoSQL 非关系型数据库【简洁版】
java·数据库·nosql
IvorySQL39 分钟前
PostgreSQL 19 新特性:基于 SQL/PGQ 实现图数据查询
数据库·sql·postgresql
jghhh0143 分钟前
C# 图片水印工具(支持9个位置)
数据库·microsoft·c#
辰海Coding1 小时前
MiniSpring框架学习笔记-JDBC 访问框架:如何抽取 JDBC 模板并隔离数据库?
java·数据库·笔记·学习·spring
救救孩子把1 小时前
01 Milvus-向量数据库基础
数据库·milvus