Mysql:Read View
在 MySQL InnoDB 中Read View读视图是 MVCC 用来判断“某个数据版本对当前查询是否可见”的规则集合。它可以理解为查询创建的一张“事务快照名单”但要注意Read View 并不会复制整张表也不保存数据本身它只记录事务可见性的边界信息。普通SELECT可以借助 Read View 读取历史版本不必等待其他事务提交也通常不需要加行锁为什么需要 Read View假设一行数据正在被其他事务修改事务 A把 balance 从 100 修改为 200但还没有提交 事务 B执行 SELECT 查询 balance事务 B 不能随便看到未提交的200否则会产生脏读。InnoDB 会通过以下信息决定读取哪个版本Read View 数据行的事务 ID Undo Log 版本链Read View 记录什么可以简化理解为四部分creator_trx_id创建 Read View 的事务 ID active_trx_ids创建时仍然活跃、未提交的事务 ID min_trx_id活跃事务中的最小事务 ID max_trx_id创建时下一个将被分配的事务 IDMySQL 源码中的具体字段名称略有不同但核心就是记录创建快照时哪些事务尚未完成以及事务 ID 的上下边界。可见性判断规则假设 Read View 创建时当前事务 ID105 活跃事务100、108 最小活跃事务 ID100 下一个事务 ID110检查某个数据版本的DB_TRX_ID时1. 是当前事务自己修改的DB_TRX_ID 105可见因为事务应该看到自己之前的修改。2. 小于最小活跃事务 IDDB_TRX_ID 90可见。说明修改这个版本的事务在 Read View 创建之前就已经提交。3. 大于等于下一个事务 IDDB_TRX_ID 110不可见。说明修改数据的事务是在 Read View 创建之后才开始的相当于“未来事务”。4. 位于两个边界之间例如DB_TRX_ID 103需要检查活跃事务列表在活跃事务列表中当时尚未提交不可见。不在活跃事务列表中当时已经提交可见。整体规则可以概括为是自己修改的 → 可见 小于最小活跃事务 ID → 可见 大于等于下一个事务 ID → 不可见 处于两者之间且仍然活跃 → 不可见 处于两者之间但已经提交 → 可见当前版本不可见怎么办InnoDB 聚簇索引记录中包含两个隐藏字段DB_TRX_ID最后修改该行的事务 ID DB_ROLL_PTR指向 Undo Log 中的历史版本如果当前记录对 Read View 不可见InnoDB 会沿着DB_ROLL_PTR找到更旧的版本最新版本事务 108 修改不可见 ↓ Undo Log 旧版本事务 103 修改可见 ↓ 返回旧版本这就是 MVCC 的多版本读取过程。MySQL 源码也会根据 Read View 检查记录事务 ID并在版本不可见时通过 Undo Log 构造旧版本。