0
0
0

MySQL :Read View 与 MVCC

2026-10-28
2026-10-28
文章摘要
|

一、Read View 是什么?

Read View 是 InnoDB 在 MVCC 中用于判断数据版本是否可见的机制。

它不是数据副本,而是记录创建快照时的事务信息,再根据这些信息判断应该读取哪个数据版本。

Read View 的四个变量

变量

含义

m_ids

创建快照时活跃的读写事务 ID 集合

min_trx_id

活跃事务中最小的事务 ID

max_trx_id

创建快照时事务 ID 的分配上界

creator_trx_id

创建 Read View 的事务 ID

二、Read View 可见性判断

核心规则:

自己事务产生的版本可见;其他事务的版本,只要在 m_ids 中,或者 trx_id >= max_trx_id,就不可见;否则可见。

例如:

m_ids = [20, 30]
min_trx_id = 20
max_trx_id = 40

版本事务 ID

是否可见

原因

10

可见

不满足不可见条件

20

不可见

在 m_ids 中

25

可见

不在 m_ids,且小于 40

30

不可见

在 m_ids 中

40

不可见

大于或等于 max_trx_id

以上假设都是其他事务产生的有效记录版本。

min_trx_id 主要用于快速判断:如果 trx_id < min_trx_id,可以直接判断可见。

如果最新版本不可见,InnoDB 会沿 Undo Log 版本链查找更旧的可见版本。

三、Read View 与事务隔离级别的关系

Read View 负责判断版本是否可见,事务隔离级别决定 Read View 什么时候创建、是否复用。

RC 和 RR 使用相同的版本可见性判断规则,主要区别在于 Read View 的创建时机。

隔离级别

Read View 创建规则

RC(读已提交)

每次普通一致性读取创建新的 Read View

RR(可重复读)

通常第一次一致性读取创建,后续复用

例如,初始余额为 100:

事务 A:第一次 SELECT → 100

事务 B:UPDATE → 200
事务 B:COMMIT

事务 A:第二次 SELECT → ?
  • RC:返回 200,因为第二次查询创建了新的 Read View。

  • RR:返回 100,因为复用第一次查询创建的 Read View。

注意:RR 下普通 BEGIN 通常不会立即创建 Read View,而是在第一次一致性读取时创建。

四、MVCC 执行流程

执行普通快照读
       ↓
根据 RC / RR 决定创建或复用 Read View
       ↓
检查当前记录版本的事务 ID
       ↓
根据 Read View 判断是否可见
       ↓
可见 → 返回该版本
不可见 → 沿 Undo Log 查找旧版本

这里讨论的是 RC、RR 下的普通快照读。SELECT ... FOR UPDATE 属于当前读,不沿用普通快照读的旧 Read View。

五、总结

MVCC = Undo Log 版本链 + Read View 可见性判断等机制。

  • Undo Log:提供历史版本。

  • Read View:判断哪个版本可见。

  • RC:每次一致性读取创建新快照。

  • RR:通常复用第一次一致性读取的快照。

一句话记忆:

Read View 的判断规则在 RC 和 RR 下相同,真正的区别是创建和复用时机。RC 每次快照读创建新的 Read View,RR 通常只在第一次快照读创建,后续复用。

支持与分享

如果这篇文章对你有帮助,欢迎分享给更多人或者给予支持!

评论