温馨提示×

温馨提示×

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

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

MVCC版本链如何管理

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

MVCC(Multi-Version Concurrency Control,多版本并发控制)是现代数据库(如 MySQL InnoDB、PostgreSQL、Oracle 等)实现高并发读写的核心机制。它通过保存数据的多个版本,让“读不阻塞写、写不阻塞读”。

下面以 MySQL InnoDB 为例,系统讲解 MVCC 版本链是如何管理的


一、MVCC 依赖的底层结构

1. 每行记录的隐藏字段

InnoDB 每行记录中,除了业务字段,还有隐藏列:

字段 含义
DB_TRX_ID 最近一次修改该行的事务 ID
DB_ROLL_PTR 回滚指针,指向 undo log 中的旧版本
DB_ROW_ID 行 ID(无主键时使用)

2. Undo Log(回滚日志)

  • 每次 UPDATE / DELETE 都会生成 undo log
  • undo log 中保存的是 该行的历史版本
  • undo log 通过 DB_ROLL_PTR 串成一条 版本链

二、版本链是如何形成的?

示例:一行数据的多次修改

初始数据:

id=1, name='A'

事务 T1(trx_id=10)修改:

UPDATE t SET name='B' WHERE id=1;

此时:

  • 当前行:name='B', DB_TRX_ID=10
  • undo log 保存旧版本:name='A'

事务 T2(trx_id=20)再次修改:

UPDATE t SET name='C' WHERE id=1;

此时:

  • 当前行:name='C', DB_TRX_ID=20
  • undo log 链:
当前行(C, trx_id=20)
   ↓ ROLL_PTR
undo(C➜B, trx_id=10)
   ↓ ROLL_PTR
undo(B➜A, trx_id=初始)

✅ 这就是 MVCC 版本链


三、ReadView(读视图)如何配合版本链?

1. 什么是 ReadView?

ReadView 是事务在快照读时生成的一个“可见性判断规则”。

包含:

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

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

对于版本链上的某一版本(trx_id = X):

情况 是否可见
X < 最小活跃事务 ID ✅ 可见(已提交)
X 在活跃事务列表中 ❌ 不可见(未提交)
X ≥ 下一个事务 ID ❌ 不可见(未来事务)
其他 ✅ 可见

3. 版本链遍历过程

当执行:

SELECT * FROM t WHERE id=1;

数据库会:

  1. 最新版本开始
  2. 用 ReadView 判断可见性
  3. 不可见 → 沿 ROLL_PTR 找上一个版本
  4. 直到找到可见版本或链结束

四、不同隔离级别下的版本链管理

1. READ COMMITTED(RC)

  • 每次 SELECT 都生成 新的 ReadView
  • 能看到“已提交的最新版本”

2. REPEATABLE READ(RR,MySQL 默认)

  • 事务第一次 SELECT 时生成 ReadView
  • 整个事务复用同一个 ReadView
  • 保证可重复读

✅ InnoDB 的 RR 通过 版本链 + ReadView 实现


五、版本链的清理(Purge)

版本链不能无限增长,需要清理:

Purge 线程负责:

  • 删除 不再被任何事务需要 的 undo 版本
  • 条件:
    • 版本对应的事务已提交
    • 没有活跃事务的 ReadView 还需要它

六、一句话总结

MVCC 版本链 = 当前数据 + undo log 历史版本 + 回滚指针

通过 ReadView 判断哪个版本对当前事务可见,实现无锁并发读写

如果你愿意,我也可以:

  • 画出版本链
  • 对比 MySQL vs PostgreSQL 的 MVCC
  • 结合 事务隔离问题(脏读/幻读) 讲清楚
向AI问一下细节

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

AI