温馨提示×

温馨提示×

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

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

数据库MVCC是什么原理

发布时间:2026-09-09 20:43:01 来源:亿速云 阅读:103 作者:小樊 栏目:数据库

MVCC(Multi-Version Concurrency Control,多版本并发控制) 是现代关系型数据库(如 MySQL InnoDB、PostgreSQL、Oracle 等)用来实现高并发读写的核心机制。它的目标是:读不阻塞写,写不阻塞读,从而提升并发性能。

下面从“为什么需要 → 核心思想 → 实现原理 → 典型例子”来说明。


一、为什么需要 MVCC

在传统锁机制下:

  • 写数据要加锁
  • 读数据也可能被阻塞

这会导致:

  • 读多写少场景性能差
  • 锁冲突严重

MVCC 的思路是:不改数据本身,而是保存多个版本,让不同事务看到不同版本的数据。


二、MVCC 的核心思想

事务在某一时刻,只能看到“它应该看到的数据版本”

也就是:

  • 已提交的数据 ✅ 可见
  • 其他事务未提交的修改 ❌ 不可见
  • 被删除的数据,对老事务仍可“看到”

三、MVCC 的基本实现原理(以 MySQL InnoDB 为例)

1. 每行数据隐藏字段

InnoDB 每行记录中隐藏了:

  • DB_TRX_ID:最近修改该行的事务 ID
  • DB_ROLL_PTR:回滚指针,指向 undo log 中的旧版本

2. Undo Log(回滚日志)

  • 每次更新数据,旧版本会写入 undo log
  • 形成一条版本链
最新版本 → 上一版本 → 上上版本 → ...

3. 事务 ID 与 ReadView

  • 每个事务有唯一 transaction_id
  • 事务开始时生成 ReadView(快照)
    • 记录:
      • 当前活跃事务列表
      • 当前最大事务 ID

4. 可见性判断规则

对于某一行数据版本:

  • 如果该版本的 DB_TRX_ID:
    • 小于 ReadView 中最小活跃事务 ID → 可见
    • 大于 当前事务 ID → 不可见
    • 属于未提交事务 → 不可见
  • 不可见就顺着 roll_ptr 找上一个版本

四、MVCC 下的两种读

1. 快照读(Snapshot Read)

  • 普通 SELECT
  • 基于 MVCC,不加锁
  • 看到的是事务开始时的数据快照
SELECT * FROM user;

2. 当前读(Current Read)

  • 加锁读
  • 读取最新已提交数据
SELECT * FROM user FOR UPDATE;
UPDATE user SET ...;

五、示例说明

事务 A(ID=10):

BEGIN;
SELECT name FROM user WHERE id=1; -- 看到 Tom

事务 B(ID=11):

BEGIN;
UPDATE user SET name='Jack' WHERE id=1;
COMMIT;

事务 A 再查:

SELECT name FROM user WHERE id=1;
  • 仍看到 Tom
  • 因为 B 的修改对 A 不可见(MVCC)

六、MVCC 的优点

✅ 读不加锁
✅ 读写不互斥
✅ 提高并发性能
✅ 避免脏读、不可重复读(RC / RR 级别)


七、MVCC 不是“万能的”

  • 不能解决更新冲突(仍需锁)
  • 长事务会导致 undo log 堆积
  • 幻读在 RR 下靠 Next-Key Lock 解决

如果你愿意,我也可以:

  • 用 PostgreSQL 的 MVCC 对比讲
  • 画 版本链 + ReadView 的图
  • 结合 面试高频问题 讲

你想从哪个角度继续?

向AI问一下细节

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

AI
助
手