MySQL :Read View 与 MVCC
一、Read View 是什么?
Read View 是 InnoDB 在 MVCC 中用于判断数据版本是否可见的机制。
它不是数据副本,而是记录创建快照时的事务信息,再根据这些信息判断应该读取哪个数据版本。
Read View 的四个变量
二、Read View 可见性判断
核心规则:
自己事务产生的版本可见;其他事务的版本,只要在
m_ids中,或者trx_id >= max_trx_id,就不可见;否则可见。
例如:
m_ids = [20, 30]
min_trx_id = 20
max_trx_id = 40以上假设都是其他事务产生的有效记录版本。
min_trx_id 主要用于快速判断:如果 trx_id < min_trx_id,可以直接判断可见。
如果最新版本不可见,InnoDB 会沿 Undo Log 版本链查找更旧的可见版本。
三、Read View 与事务隔离级别的关系
Read View 负责判断版本是否可见,事务隔离级别决定 Read View 什么时候创建、是否复用。
RC 和 RR 使用相同的版本可见性判断规则,主要区别在于 Read View 的创建时机。
例如,初始余额为 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 通常只在第一次快照读创建,后续复用。
