ReadView是MySQL MVCC中用于快照读可见性判断的运行时结构体,非数据快照;含creator_trx_id、m_ids、min_trx_id、max_trx_id四字段,按固定顺序判断版本行可见性;RC每次SELECT新建,RR首次SELECT创建后复用。

MySQL MVCC 中的 ReadView 不是数据快照,而是一套运行时生成的可见性判定结构体。它不保存数据本身,只记录事务可见性的判断依据,核心作用是在快照读(普通 SELECT)时,决定版本链中哪一行数据对当前事务可见。
ReadView 的四个核心字段
每个 ReadView 包含且仅包含以下四个关键字段:
- creator_trx_id:创建该 ReadView 的事务 ID。用于识别“自己改的数据”——只要某行的 DB_TRX_ID 等于它,就直接可见。
- m_ids:生成时刻所有活跃(未提交)事务的 ID 集合。这是判断“别人改但还没提交”的核心依据。
- min_trx_id:m_ids 中最小的事务 ID。代表当时最早开始却仍未提交的事务,比它更小的事务一定已提交。
- max_trx_id:下一个将被分配的事务 ID(即当前已用最大 ID + 1),不是活跃事务中的最大值。用于识别“未来才启动的事务”。
可见性判断的四步严格顺序
对版本链中某行的 DB_TRX_ID(记为 row_trx_id),InnoDB 按固定顺序逐条比对,满足任一条件即终止判断:
- 若 row_trx_id == creator_trx_id → 当前行由本事务修改,可见
- 若 row_trx_id < min_trx_id → 修改者在 ReadView 创建前已提交,可见
- 若 row_trx_id >= max_trx_id → 修改者在 ReadView 创建后才启动,不可见
- 若 min_trx_id <= row_trx_id < max_trx_id → 查 row_trx_id 是否在 m_ids 中:
✓ 在列表中 → 修改事务尚未提交,不可见
✗ 不在列表中 → 修改事务已提交,可见
不同隔离级别下 ReadView 的生成时机
生成时机直接决定一致性行为:
- READ COMMITTED(RC):每次执行普通 SELECT 都新建一个 ReadView。因此同一事务内多次查询可能看到其他事务新提交的数据。
- REPEATABLE READ(RR):仅在事务中第一次普通 SELECT(或 LOCK IN SHARE MODE 等一致性读)时创建 ReadView,后续所有快照读复用它。这是“可重复读”的技术来源。
- READ UNCOMMITTED:跳过 ReadView,直接读最新版本,不做可见性检查。
- SERIALIZABLE:退化为加锁读,不走 MVCC 路径,也不依赖 ReadView。
容易忽略的关键细节
这些点直接影响你对现象的理解:
- ReadView 只在一致性读(普通 SELECT)时生效;SELECT ... FOR UPDATE、UPDATE、DELETE 是当前读,直接访问最新版本并加锁。
- 显式开启事务(BEGIN / START TRANSACTION)不会立即生成 ReadView,而是在首次快照读时才创建。
- 长事务会持续保留在后续 ReadView 的 m_ids 中,导致 undo log 无法清理、磁盘空间增长、purge 进程受阻。
- 只读事务(如 START TRANSACTION READ ONLY)的 creator_trx_id = 0;普通自动提交的 SELECT 仍有真实事务 ID,creator_trx_id ≠ 0。


















