聚簇记录
animation part- 它解决什么问题?
- 这一行的最新值放在哪里?
- 动画里对应哪个部件?
- 动画中间的 account(id=1) 记录卡片。
- 面试时一句话
- 聚簇记录头部保存最新版本,快照读能不能读它,要交给 ReadView 判断。
MySQL 面试 · MVCC Visual Lab
先别背 ReadView。先回答一个真实问题:同一行被另一个事务更新并提交后, T1 第二次普通 SELECT 到底该看到旧值还是新值?
MVCC 不是凭空变出旧值。它靠四个零件合作:聚簇记录保存最新版本,DB_TRX_ID 标记谁改的,DB_ROLL_PTR 指向旧版本,ReadView 决定当前事务能看哪个版本。
左边看舞台,右边看解释面板。每一步都固定回答:当前发生了什么、MySQL 内部做了什么、面试怎么回答。
你正俯瞰整个执行空间。事务 T1(蓝,trx_id=101)先读 account(id=1,value=100),事务 T2(橙,trx_id=102)稍后才更新并提交,最后 T1 再读一次。
时间线只有一个核心问题:T1 第一次 SELECT 创建的 ReadView,会不会允许它在第二次 SELECT 时看到 T2 后来提交的 V200。
这道题考的是:普通 SELECT 是 consistent read / 快照读,以及 RR、RC 的 ReadView 创建时机。
你正俯瞰整个执行空间。事务 T1(蓝,trx_id=101)先读 account(id=1,value=100),事务 T2(橙,trx_id=102)稍后才更新并提交,最后 T1 再读一次。
trx_id == creator_trx_id是当前事务自己改的 → 可见
trx_id < up_limit_id快照创建前就已提交 → 可见
trx_id >= low_limit_id快照创建后才开始 → 不可见
up_limit_id <= trx_id < low_limit_id看是否在 active_trx_ids 里:在 → 不可见;不在 → 可见
动画跑完以后再对齐概念:普通 SELECT 和锁定读/写不是同一条路径。
快照读SELECT ...当前读UPDATE / DELETE / FOR UPDATE| 对比项 | RC 读已提交 | RR 可重复读 |
|---|---|---|
| ReadView 创建时机 | 每次快照读都新建 | 只在第一次快照读建一次 |
| 同一事务多次读 | 可能读到不同值 | 复用首个快照,保持一致 |
| 看到别人已提交的修改 | 能(更新鲜) | 不能(更一致) |
| 概念 | 是什么 | RR 下的行为 |
|---|---|---|
| 快照读 | 普通 SELECT,读 ReadView 可见版本 | 复用首个 ReadView |
| 当前读 | 锁定读/写,读最新已提交版本 | 读最新 + 加锁 |
| ReadView | 判断版本可见性的快照 | 第一次快照读时建立 |
| undo 版本链 | 保存旧版本供回溯 | 长事务会拖住 purge |
现在再回到面试题:按时间线、版本链、隔离级别三段回答。
面试官意图:考你能否用 ReadView 和 undo 版本链解释,而不是说 MySQL 把写事务锁住了。
A 第一次快照读建立 ReadView 后,RR 会复用这个快照。B 后续提交的新版本对这个 ReadView 不可见,A 会沿 undo 版本链找到旧版本。
面试官意图:考你能否区分快照新鲜度和事务一致性。
RC 每次 consistent read 建新 ReadView,所以能看到已提交的新版本;RR 同一事务复用第一次 consistent read 的 ReadView。
面试官意图:考你是否知道普通 SELECT 和锁定读/写语句走不同并发控制路径。
普通 SELECT 多数是快照读,按 ReadView 读可见版本;当前读读取最新版本,如 UPDATE、DELETE、SELECT FOR UPDATE,会配合锁控制并发。
RR 下 T1 第一次快照读建立 ReadView:creator_trx_id=101、active_trx_ids=[101]、up_limit_id=101、low_limit_id=102。
T2 更新后的版本 trx_id=102,满足 102 >= low_limit_id(102),对 T1 的第一次 ReadView 不可见,所以 T1 沿 DB_ROLL_PTR 找到 V100。
V100.trx_id=100,满足 100 < up_limit_id(101),因此 RR 下 T1 第二次仍读到 100。
如果是 RC,每次读新建 ReadView,就会读到 200。
最后检查是否会说人话,也会做工程判断。
这部分默认折叠,避免打断主学习流。