你想深入掌握 Read View 的结构和工作原理,这是理解 MVCC 快照读的核心 ——Read View 就像 MVCC 的 “版本安检员”,决定了当前事务能看到版本链中的哪个版本。接下来我会先拆解 Read View 的核心结构,再用通俗的逻辑 + 实例讲清它的工作原理,让你彻底吃透。
一、Read View 的核心结构(4 个关键参数)
Read View 是 InnoDB 在事务执行快照读时生成的一个 “版本可见性判断规则集”,本质是一个内存数据结构,包含 4 个不可变的核心参数:
| 参数名 | 中文含义 | 作用 |
|---|---|---|
m_ids | 活跃事务 ID 列表 | 记录生成 Read View 时,当前数据库中所有未提交的事务 ID(即 “活跃事务”) |
min_trx_id | 最小活跃事务 ID | m_ids中的最小值,是判断版本可见性的 “下限” |
max_trx_id | 下一个分配的事务 ID | 系统即将分配的下一个事务 ID(大于当前所有已分配的事务 ID),是 “上限” |
creator_trx_id | 创建 Read View 的事务 ID | 生成这个 Read View 的当前事务 ID(即 “自己” 的事务 ID) |
补充说明:
- 事务 ID 是 InnoDB 全局递增的唯一编号,新事务的 ID 永远比旧事务大;
- Read View 生成后,这 4 个参数就固定不变(可重复读隔离级别下),不会随其他事务提交 / 开启变化。
二、Read View 的工作原理(核心判断规则)
Read View 的核心作用是:遍历版本链时,判断某个版本是否对当前事务 “可见”。
它的判断逻辑是一套 “自上而下” 的规则,针对版本链中某个版本的DB_TRX_ID(该版本的创建事务 ID):
核心判断规则(优先级从高到低)
自己修改的版本,永远可见如果
版本的 DB_TRX_ID = creator_trx_id(当前事务自己修改的版本),直接判定为可见。→ 比如事务 101 自己更新了数据,它的快照读能看到自己修改的版本。已提交事务的版本,可见如果
版本的 DB_TRX_ID < min_trx_id(创建该版本的事务,在生成 Read View 时已经提交),判定为可见。→ 比如min_trx_id=102,版本的DB_TRX_ID=101(事务 101 已提交),这个版本对当前事务可见。未来事务的版本,不可见如果
版本的 DB_TRX_ID >= max_trx_id(创建该版本的事务,在生成 Read View 时尚未创建),判定为不可见。→ 比如max_trx_id=105,版本的DB_TRX_ID=106(事务 106 是 “未来” 的),这个版本还没产生,自然不可见。活跃事务的版本,不可见如果
min_trx_id ≤ 版本的 DB_TRX_ID < max_trx_id,且版本的 DB_TRX_ID 在 m_ids 列表中(创建该版本的事务还没提交),判定为不可见;反之,如果版本的 DB_TRX_ID 不在 m_ids 列表中(事务已提交),则可见。→ 比如m_ids=[102,103],版本的DB_TRX_ID=102(在列表中,未提交)→ 不可见;DB_TRX_ID=104(不在列表中,已提交)→ 可见。
规则执行流程(配合版本链)
当事务执行快照读时,Read View 会按以下步骤找 “可见版本”:
三、Read View 生成时机(隔离级别影响)
Read View 的生成时机直接决定了 “可重复读” 和 “读已提交” 的差异,这是面试高频考点:
| 隔离级别 | Read View 生成时机 | 效果 |
|---|---|---|
| 可重复读(RR) | 事务中第一次执行快照读时生成,后续复用 | 整个事务内多次快照读用同一个 Read View,保证 “可重复读”(结果一致) |
| 读已提交(RC) | 每次执行快照读时都生成新的Read View | 每次读都用最新的活跃事务列表判断,能看到其他事务刚提交的版本(不可重复读) |
四、实例演示(Read View + 版本链 联动)
沿用之前的例子:user表 id=1 的版本链为:当前版本(102: 王五)→ 历史版本1(101: 李四)→ 历史版本2(0: 张三)
场景:事务 103 执行快照读(可重复读隔离级别)
- 生成 Read View 时,活跃事务列表
m_ids=[103],min_trx_id=103,max_trx_id=104,creator_trx_id=103。 - 第一步:判断当前版本(102: 王五)的
DB_TRX_ID=102 < min_trx_id=103→ 可见?→ 是!直接返回 “王五”。
场景:事务 104 在事务 102 未提交时执行快照读
- 生成 Read View 时,活跃事务列表
m_ids=[102,104],min_trx_id=102,max_trx_id=105,creator_trx_id=104。 - 第一步:判断当前版本(102: 王五)的
DB_TRX_ID=102→ 在m_ids中(未提交)→ 不可见; - 第二步:遍历版本链,读取历史版本 1(101: 李四)→
DB_TRX_ID=101 < min_trx_id=102→ 可见; - 结果:返回 “李四”。
总结
- Read View 核心结构:由
m_ids、min_trx_id、max_trx_id、creator_trx_id4 个参数组成,是版本可见性的判断规则; - 工作原理:通过对比版本的
DB_TRX_ID和 Read View 参数,遍历版本链找到第一个可见版本; - 关键差异:可重复读(RR)复用 Read View,读已提交(RC)每次生成新的,这是二者隔离性差异的核心原因。