温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

数据库为何引入MVCC

发布时间:2026-07-15 05:09:49 来源:亿速云 阅读:97 作者:小樊 栏目:数据库

数据库引入 MVCC(Multi-Version Concurrency Control,多版本并发控制),核心目的是 在保证数据一致性的前提下,提高并发性能,减少锁的使用。下面从问题背景、MVCC 解决的问题、以及它带来的好处来解释。


一、没有 MVCC 时的问题

在早期的数据库并发控制中,常用 锁机制 来保证一致性,比如:

1️⃣ 读写冲突严重

  • 写操作会阻塞读
  • 读操作也可能阻塞写

例如:

  • 事务 A 正在更新一行数据
  • 事务 B 想要读取这行数据 → 必须等 A 提交或回滚

这会造成:

  • 并发性能差
  • 锁等待、死锁问题多

2️⃣ 锁粒度难以权衡

  • 锁粒度太小:管理复杂
  • 锁粒度太大:并发度低

二、MVCC 的核心思想

对同一数据保存多个版本,读写互不阻塞

MVCC 的基本思路是:

  • 写操作:创建新版本,而不是覆盖旧数据
  • 读操作:根据事务的“可见性规则”,读取合适的旧版本

✅ 读不加锁
✅ 写不阻塞读
✅ 读不阻塞写


三、MVCC 解决了哪些问题

✅ 1. 提高并发性能(最重要)

场景 锁机制 MVCC
读-写 冲突 不冲突
写-读 冲突 不冲突
并发度 低 高

✅ 2. 避免脏读、不可重复读(在合适隔离级别下)

MVCC 配合事务快照(Read View)可以实现:

  • RC(Read Committed)
  • RR(Repeatable Read)

而无需频繁加锁。


✅ 3. 减少锁的使用和死锁概率

  • 大多数读操作 完全不需要加锁
  • 写操作只锁定必要的数据版本

✅ 4. 支持一致性非锁定读(Consistent Non-locking Read)

例如 MySQL InnoDB:

SELECT * FROM orders WHERE id = 1;
  • 不会加锁
  • 不会阻塞写操作
  • 返回的是事务开始时的“一致性快照”

四、MVCC 的典型实现方式

1️⃣ 版本链(Undo Log)

以 MySQL InnoDB 为例:

  • 每行数据有隐藏字段:
    • trx_id(最后修改事务 ID)
    • roll_pointer(指向 undo log)
  • 修改数据时:
    • 旧版本存入 undo log
    • 形成版本链

2️⃣ 快照(Read View)

事务开始时创建 Read View,用来判断:

  • 哪些版本“对我可见”
  • 哪些版本“还没提交,不可见”

五、MVCC 不是银弹

❌ 1. 只适用于某些隔离级别

  • 通常 不适用于 Serializable
  • Serializable 往往需要额外加锁

❌ 2. 写-写冲突仍然存在

  • 两个事务同时修改同一行 → 仍需锁(如行锁)

❌ 3. 存储和清理成本

  • 需要维护多版本数据
  • 需要后台清理(如 MySQL Purge 线程)

六、一句话总结

数据库引入 MVCC,是为了在不加锁的情况下实现高并发读取,同时保证事务隔离性和数据一致性。

如果你愿意,我可以:

  • 用 MySQL InnoDB 举例详细讲 MVCC 流程
  • 对比 MVCC vs 锁机制
  • 画一张 版本链 + Read View 的示意图
向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI
助
手