美文网首页
MVCC 的实现原理

MVCC 的实现原理

作者: 西谷haul | 来源:发表于2025-04-09 18:13 被阅读0次

🚀 MVCC 实现原理详解(以 MySQL InnoDB 为例)

一、什么是 MVCC?

MVCC(Multi-Version Concurrency Control,多版本并发控制) 是一种在数据库中实现高并发、读写分离的机制。

它的核心思想是:

通过为每个事务提供数据的“快照”,避免加锁,实现读写并发而互不阻塞。


二、MVCC 的核心机制

✅ 1. 读操作:读取历史版本(快照读)

  • 不会阻塞写操作,也不会被写操作阻塞
  • 读取的是事务开始时可见的数据快照

✅ 2. 写操作:创建新版本,不修改原数据

  • 写入新版本数据,旧版本保存在 undo log 中
  • 通过 roll_pointer 记录旧版本地址,便于其他事务读取

三、InnoDB 中的实现细节

🧱 每行记录包含的隐藏字段

字段名 作用
trx_id 插入或最后修改该行的事务 ID
roll_pointer 指向 undo log 中的旧版本记录
row_id 行的唯一标识(非 MVCC 核心字段)

📝 Undo Log(撤销日志)

当执行 UPDATEDELETE 时,旧版本会被写入 undo log:

-- 初始记录:
id = 1, name = 'Tom', trx_id = 100, roll_pointer = null

-- 事务 200 执行 UPDATE name = 'Jerry'
id = 1, name = 'Jerry', trx_id = 200, roll_pointer → (Tom, trx_id=100)

四、Read View(一致性视图)

每个事务在执行第一条 SELECT 时,会创建一个 Read View,决定它能看到哪些版本的数据。

Read View 包含的信息如下:

属性 说明
活跃事务 ID 列表 当前还没提交的事务
当前事务 ID 自己的事务 ID
最小活跃事务 ID 可见性的边界
最大活跃事务 ID 当前系统中分配的最大事务 ID

五、可见性判断规则

当前事务要读取一行记录时,会对其 trx_id 进行如下判断:

情况 是否可见 原因
trx_id < min_active_id ✅ 可见 已提交
trx_id == 当前事务 ID ✅ 可见 自己的数据
trx_id 在活跃事务列表中 ❌ 不可见 尚未提交
trx_id > max_id ❌ 不可见 是未来的事务

如果当前版本不可见,就会通过 roll_pointer 回溯旧版本,直到找到一个可见的版本。


六、MVCC 的优势

优点 说明
✅ 非阻塞读 避免了读写互相阻塞
✅ 高并发性能 适合 OLTP 类型的并发读写场景
✅ 支持事务隔离级别 READ COMMITTED 和 REPEATABLE READ 支持

七、MVCC 的限制与注意事项

限制 说明
🚫 仅适用于特定隔离级别 不支持 Serializable 级别的快照读
🚫 对 SELECT ... FOR UPDATE 无效 这种加锁语句不走快照
🚫 Undo Log 空间占用 长事务可能导致 undo bloating

八、总结图解

+-------------------------------------+
|        每行记录结构(数据行)       |
+-------------------------------------+
| data fields                         |
| trx_id         ← 当前事务ID         |
| roll_pointer   ← 指向旧版本(undo) |
+-------------------------------------+
          |
          ↓
    +--------------------+
    |     Undo Log       |
    |   存储历史版本数据 |
    +--------------------+
          ↖
          |
    Read View 判断可见性

相关文章

网友评论

      本文标题:MVCC 的实现原理

      本文链接:https://www.haomeiwen.com/subject/lfffbjtx.html