温馨提示×

温馨提示×

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

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

MVCC怎么保证一致性

发布时间:2026-09-30 10:07:20 来源:亿速云 阅读:88 作者:小樊 栏目:数据库

MVCC(Multi-Version Concurrency Control,多版本并发控制)是数据库(如 MySQL InnoDB、PostgreSQL)用来在不加锁或少加锁的情况下,实现并发读写并保证一致性的核心机制。

下面从「一致性问题是什么」→「MVCC 怎么做」→「为什么能保证一致性」三个层次说明。


一、先明确:MVCC 保证的是哪种一致性?

MVCC 主要保证的是 事务级一致性(隔离性),尤其是:

  • 读不阻塞写,写不阻塞读
  • 每个事务看到的是一致的数据快照
  • 在 REPEATABLE READ / READ COMMITTED 下防止脏读、不可重复读(部分情况防幻读)

它不直接保证:

  • 跨事务的业务一致性(要靠应用或锁)
  • 写冲突(要靠锁或冲突检测)

二、MVCC 的核心思想(一句话)

给数据存多个版本,让不同事务看到自己“该看到”的那个版本


三、MVCC 是怎么实现的(以 InnoDB 为例)

1. 每行数据隐藏字段

InnoDB 每行记录包含:

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

2. Undo Log(版本链)

每次更新:

  • 旧数据写入 undo log
  • 新数据更新,并指向旧版本

形成一条 版本链:

最新版本 → 上一版本 → 上上版本 → ...

3. 事务 ID + ReadView(关键)

每个事务有:

  • 自己的事务 ID
  • 启动时生成 ReadView(快照)

ReadView 记录:

  • 当前活跃事务列表
  • 最小事务 ID
  • 下一个将分配的事务 ID

4. 可见性判断规则(核心)

一个数据版本对当前事务可见,当且仅当:

✅ 修改该版本的事务:

  • 已提交
  • 不在当前 ReadView 的活跃事务中
  • 事务 ID < 当前事务 ID(或符合快照规则)

否则:

  • 顺着 roll_ptr 找上一个版本
  • 直到找到可见版本

四、MVCC 如何保证一致性(举例)

场景:两个事务并发

T1: 开始事务(ReadView A)
T2: 开始事务(ReadView B)

T2: UPDATE user SET age=30 WHERE id=1;
T2: COMMIT;

T1: SELECT age FROM user WHERE id=1;

结果:

  • T1 看到的是 T2 修改前的版本
  • 因为 T1 的 ReadView 认为 T2 不可见

✅ 保证了 可重复读一致性


五、MVCC 能防什么?不能防什么?

✅ 能防

问题 是否解决
脏读 ✅
不可重复读(RR) ✅
读写互相阻塞 ✅

❌ 不能防

问题 说明
写写冲突 靠锁(行锁)
幻读(部分) 需 Next-Key Lock
业务一致性 需事务 + 逻辑

六、一句话总结

MVCC 通过“数据多版本 + 事务快照(ReadView)+ 可见性规则”,让每个事务只看到符合自己一致性视图的数据,从而在不加锁的情况下保证读一致性。

如果你愿意,我也可以:

  • 用 PostgreSQL 的 MVCC 对比讲
  • 画 版本链 + ReadView 示意图
  • 结合 隔离级别 深入讲
向AI问一下细节

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

AI
助
手