MVCC(Multi-Version Concurrency Control,多版本并发控制)是现代数据库(如 MySQL InnoDB、PostgreSQL、Oracle 等)实现高并发读写的核心机制。它通过保存数据的多个版本,让“读不阻塞写、写不阻塞读”。
下面以 MySQL InnoDB 为例,系统讲解 MVCC 版本链是如何管理的。
InnoDB 每行记录中,除了业务字段,还有隐藏列:
| 字段 | 含义 |
|---|---|
DB_TRX_ID |
最近一次修改该行的事务 ID |
DB_ROLL_PTR |
回滚指针,指向 undo log 中的旧版本 |
DB_ROW_ID |
行 ID(无主键时使用) |
DB_ROLL_PTR 串成一条 版本链初始数据:
id=1, name='A'
UPDATE t SET name='B' WHERE id=1;
此时:
name='B', DB_TRX_ID=10name='A'UPDATE t SET name='C' WHERE id=1;
此时:
name='C', DB_TRX_ID=20当前行(C, trx_id=20)
↓ ROLL_PTR
undo(C➜B, trx_id=10)
↓ ROLL_PTR
undo(B➜A, trx_id=初始)
✅ 这就是 MVCC 版本链
ReadView 是事务在快照读时生成的一个“可见性判断规则”。
包含:
对于版本链上的某一版本(trx_id = X):
| 情况 | 是否可见 |
|---|---|
| X < 最小活跃事务 ID | ✅ 可见(已提交) |
| X 在活跃事务列表中 | ❌ 不可见(未提交) |
| X ≥ 下一个事务 ID | ❌ 不可见(未来事务) |
| 其他 | ✅ 可见 |
当执行:
SELECT * FROM t WHERE id=1;
数据库会:
ROLL_PTR 找上一个版本SELECT 都生成 新的 ReadViewSELECT 时生成 ReadView✅ InnoDB 的 RR 通过 版本链 + ReadView 实现
版本链不能无限增长,需要清理:
MVCC 版本链 = 当前数据 + undo log 历史版本 + 回滚指针
通过 ReadView 判断哪个版本对当前事务可见,实现无锁并发读写
如果你愿意,我也可以:
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。