MVCC(Multi-Version Concurrency Control,多版本并发控制)是一种数据库并发控制机制,核心思想是:
对同一行数据保留多个历史版本,读写互不阻塞,通过版本判断可见性来实现一致性读。
下面从“为什么需要 → 怎么工作 → 关键组成 → 举例 → 优缺点”来理解。
传统并发控制方式的问题:
MVCC 的目标:
✅ 读不加锁
✅ 读写不冲突
✅ 提高并发性能
数据不是直接覆盖更新,而是保留多个版本,通过“版本可见性规则”决定当前事务能看到哪个版本。
一句话总结:
更新 = 新增版本;删除 = 标记删除;查询 = 找对自己可见的版本
以 MySQL InnoDB 为例:
InnoDB 给每一行记录加了两个隐藏字段:
| 字段 | 含义 |
|---|---|
trx_id |
最后一次修改该行的事务 ID |
roll_pointer |
指向 undo log(旧版本数据) |
实际还有
row_id,但和 MVCC 关系不大
当前行
↓
上一个版本(undo)
↓
再上一个版本(undo)
事务读数据时,会沿着版本链找“对自己可见”的版本。
Read View 是 MVCC 判定的核心
一个 Read View 包含:
m_ids:当前活跃的事务 ID 列表min_trx_id:最小活跃事务 IDmax_trx_id:下一个将被分配的事务 IDcreator_trx_id:创建该 Read View 的事务 ID对于某条记录版本 trx_id:
if trx_id < min_trx_id
→ 可见(已提交)
else if trx_id >= max_trx_id
→ 不可见(未来事务)
else if trx_id 在 m_ids 中
→ 不可见(未提交)
else
→ 可见
如果不可见,就沿着 undo log 往旧版本找。
id = 1, value = 100
UPDATE t SET value = 200 WHERE id = 1;
trx_id = 100SELECT value FROM t WHERE id = 1;
trx_id = 100 在活跃事务中value = 100✅ 事务 B 读到的不是最新数据,而是历史版本
| 问题 | MVCC 的解决方式 |
|---|---|
| 读写冲突 | 读不加锁 |
| 不可重复读 | 一致性 Read View |
| 幻读(部分) | 快照读 |
| 长事务阻塞 | 历史版本可访问 |
⚠️ 注意:
MVCC 不能完全解决幻读,InnoDB 在 RR 隔离级别下通过 Next-Key Lock 补充解决。
✅ 高并发 OLTP
✅ 读多写少
✅ 需要一致性读
✅ 长事务查询
MVCC = 数据多版本 + undo log + Read View + 可见性判断
通过“读历史版本”实现 非锁定一致性读,从而提升并发性能。
如果你愿意,我也可以:
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。