Read View 在 MVCC 里如何工作的?
把数据库想象成一间“时间照相馆”。
每当你开启一个事务,前台就给你拍一张“快照门票”(Read View),上面写了三行关键信息:
1. 此刻正在活跃(还没提交)的所有事务 ID 列表
(仍在暗房里洗照片的客人名单)
2. 下一个将分配的事务 ID(下一位客人的号码)
3. 你自己的事务 ID(你的号码)
拿着这张门票,你可以随便翻阅整本相册(数据所有历史版本),但只看**符合规则的旧照片**——这就是 MVCC 的魔法。
------------------------------------------------
一条顺口溜:
“号码比我小,且不在黑名单,才给我看;否则往前翻更早的照片。”
------------------------------------------------
直观三步:
1. 每行数据自带两个隐藏列:
`created_by` = 拍这张照片的事务号
`deleted_by` = 撕掉这张照片的事务号(没撕就是空)
2. 你拿着门票比对:
• 如果 `created_by` ≥ 我的「下一位号码」→ 这张照片是未来人拍的,跳过。
• 如果 `created_by` 在我的活跃名单里 → 拍照的人还没结账,跳过。
• 如果 `deleted_by` 存在且 ≤ 我的事务号 → 这张照片已被我或更早的人撕掉,跳过。
只有通过全部过滤的那一张,才是你在当前快照里能看到的版本。
3. 不同隔离级别换门票:
• Read Committed:每次查询都重新拍一张门票(读取最新已提交)。
• Repeatable Read:整个事务只用最开始的门票(保证可重复读)。
------------------------------------------------
一页图就记住:
```
门票(Read View)
┌────────┬────────────┐
│ 我的ID │ 100 │
│ 活跃ID │ 97 98 99 │
│ 下一ID │ 101 │
└────────┴────────────┘
数据行各版本
┌─数据值─┬created_by┬deleted_by┐
│ Alice │ 96 │ — │ ← 给你看(96 < 100 且不在活跃)
│ Bob │ 98 │ — │ ← 不给你看(98 在活跃)
│ Carol │ 95 │ 99 │ ← 不给你看(被 99 撕了)
└────────┴──────────┴──────────┘
```
就这么简单:Read View 就是一张“时间过滤门票”,MVCC 靠它让你看到过去某一瞬间的一致世界。