温馨提示×

温馨提示×

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

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

多版本并发控制怎实现

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

多版本并发控制(MVCC,Multi-Version Concurrency Control)是一种通过保存数据的多个版本来实现并发读写互不阻塞的机制,广泛用于 MySQL(InnoDB)、PostgreSQL、Oracle 等数据库。

下面从核心思想 → 常见实现方式 → 以 MySQL InnoDB 为例 → 优缺点来讲。


一、MVCC 的核心思想

读不加锁,写不阻塞读

  • 每次更新数据,不直接覆盖旧值
  • 而是生成新版本,旧版本保留
  • 读操作根据可见性规则读取合适的版本

结果:

  • 读和写可以并行
  • 避免大量锁竞争

二、MVCC 的通用实现要素

大多数数据库 MVCC 都依赖以下组件:

1. 版本信息(隐藏字段)

每行数据通常包含:

  • 创建版本号(事务 ID)
  • 删除 / 过期版本号
  • 回滚指针(指向旧版本)

2. 事务 ID(TRX_ID)

  • 每个事务有唯一、递增的 ID
  • 用来判断“哪个版本对哪个事务可见”

3. 快照(Snapshot)

  • 事务开始时获取一个“快照”
  • 决定能看到哪些数据版本

4. Undo Log(回滚日志)

  • 保存旧版本数据
  • 用于构造历史版本

三、以 MySQL InnoDB 为例

1. 每行记录的隐藏列

InnoDB 每行包含:

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

2. 事务视图(ReadView)

事务在读数据时生成 ReadView,包含:

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

3. 可见性判断规则(简化)

对某一行版本:

  • 如果 DB_TRX_ID < 当前事务 ID 且已提交 → 可见
  • 如果 DB_TRX_ID 在活跃事务中 → 不可见
  • 否则通过 undo log 找上一个版本

4. 更新流程

  1. 旧版本写入 undo log
  2. 修改当前行
  3. 更新 DB_TRX_ID
  4. 修改 DB_ROLL_PTR

5. 隔离级别与 MVCC

  • READ COMMITTED:每次读都生成新 ReadView
  • REPEATABLE READ(MySQL 默认):事务内共用一个 ReadView

四、MVCC 的典型流程示例

T1: BEGIN
T2: BEGIN
T2: UPDATE user SET age=20 WHERE id=1;
T1: SELECT age FROM user WHERE id=1; -- 看到旧值
T2: COMMIT
T1: SELECT age FROM user WHERE id=1; -- 仍看到旧值(RR)

✅ 无锁读
✅ 一致性视图


五、MVCC 的优点

  • 读不阻塞写,写不阻塞读
  • 高并发性能好
  • 天然支持一致性读

六、MVCC 的问题与代价

1. 版本膨胀

  • 旧版本堆积
  • 需要 Purge 线程清理

2. 写冲突仍存在

  • 更新同一行仍可能冲突
  • 通常配合行锁使用

3. 实现复杂

  • undo log
  • 可见性判断
  • 垃圾回收

七、一句话总结

MVCC 通过“保存多个数据版本 + 事务快照 + 可见性规则”,实现无锁一致性读,是数据库高并发的核心技术。

如果你愿意,我也可以:

  • 用 PostgreSQL 的 MVCC 对比讲
  • 画一张 MVCC 版本链示意图
  • 结合 面试角度讲 MVCC
向AI问一下细节

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

AI
助
手