温馨提示×

温馨提示×

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

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

数据库如何用MVCC并发

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

MVCC(Multi-Version Concurrency Control,多版本并发控制)是现代关系型数据库实现高并发读写的核心技术。它的核心思想是:写操作不阻塞读,读操作不阻塞写,通过保存数据的多个版本来实现并发控制。

下面从原理 → 实现机制 → 不同数据库对比 → 优缺点系统讲清楚。


一、MVCC 的核心思想

同一份数据,不同事务看到不同“版本”

  • 读:看到的是快照(历史版本)
  • 写:生成新版本,旧版本保留
  • 通过版本判断,决定事务能否看到某条数据

✅ 避免:

  • 读等写(避免锁读)
  • 写等读(避免锁写)

二、MVCC 的关键组成

1️⃣ 事务 ID(Transaction ID)

  • 每个事务开始时被分配一个 唯一、递增的 txid
  • 用于判断“谁能看到谁”

2️⃣ 数据版本链

每条记录通常包含:

  • 创建事务 ID(created_txid)
  • 删除 / 过期事务 ID(deleted_txid)
  • 指向上一个版本的指针(undo / rollback pointer)

3️⃣ 快照(Snapshot)

  • 事务启动时记录当前活跃事务列表
  • 决定哪些版本“对我可见”

三、MVCC 读可见性规则(通用逻辑)

一个数据版本对事务 T 可见,通常满足:

1. 创建事务 < T 且已提交
2. 删除事务不存在 或 删除事务 > T 或 未提交

简单理解:

  • 在我之前提交的数据:可见
  • 在我之后修改的数据:不可见
  • 未提交的数据:永远不可见

四、典型数据库实现对比

✅ MySQL(InnoDB)

实现方式:

  • 隐藏字段:
    • DB_TRX_ID(事务ID)
    • DB_ROLL_PTR(回滚指针)
  • Undo Log 保存旧版本
  • ReadView 判断可见性

隔离级别与 MVCC:

隔离级别 MVCC 行为
Read Committed 每次读创建快照
Repeatable Read 事务开始创建快照(默认)
Serializable 退化成锁

示例:

-- 事务A
BEGIN;
UPDATE user SET age=20 WHERE id=1;

-- 事务B(不阻塞)
SELECT * FROM user WHERE id=1; -- 看到旧版本

✅ PostgreSQL

实现方式:

  • 每行有:
    • xmin(创建事务)
    • xmax(删除事务)
  • 无 undo log,靠 事务状态 + 多版本行
  • VACUUM 清理旧版本

特点:

  • 读永远不会被阻塞
  • 更新 = 插入新行 + 标记旧行失效

✅ Oracle

  • 使用 Undo Tablespace
  • 读一致性和 MVCC 原生支持
  • 语句级 / 事务级快照

五、MVCC 解决的问题

✅ 高并发 ✅ 读写互不阻塞 ✅ 避免脏读、不可重复读(特定级别)


六、MVCC 的问题与代价

❌ 1. 存储空间膨胀

  • 多版本 → 表/Undo 增大
  • 需要:
    • MySQL:purge
    • PG:VACUUM

❌ 2. 写冲突仍存在

  • 两个事务改同一行 → 后者阻塞或失败
  • MVCC ≠ 无锁写

❌ 3. 长事务风险

  • 长事务阻止旧版本清理
  • 导致:
    • 表膨胀
    • 性能下降

七、MVCC vs 锁

对比项 MVCC 锁
读性能 高 低
写冲突 仍有 强
实现复杂度 高 低
适用场景 OLTP 强一致写

八、一句话总结

MVCC 用“数据多版本 + 快照读”换并发性能,是数据库高并发的基石。

如果你愿意,我可以:

  • 用 图 画 MVCC 版本链
  • 结合 面试问题 讲
  • 对比 MySQL vs PG MVCC 细节

你想从哪个角度继续?

向AI问一下细节

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

AI
助
手