Skip to content

什么是MVCC

约 890 字大约 3 分钟

MySQL小红书

2025-03-14

⭐ 题目日期:

小红书 - 2024/11/11

📝 题解:

MVCCMulti-Version Concurrency Control) 是一种数据库并发控制技术,通过维护数据的多个版本来实现高并发的读写操作,避免传统锁机制带来的性能瓶颈。其核心思想是:每个事务看到的数据版本独立,读操作不阻塞写操作,写操作也不阻塞读操作


核心原理

  1. 数据版本化
    1. 每次对数据的修改(增删改)会生成一个新版本,旧版本保留在数据库中(通过 undo log 或时间戳标记)。
    2. 不同事务根据其启动时间或隔离级别,访问对应的数据版本。
  2. 快照读(Snapshot Read)
    1. 事务读取数据时,基于某个时间点的快照(如事务开始时的数据版本),而非最新数据。
    2. 读操作不会因其他事务的写操作而阻塞。
  3. 版本链管理
    1. 每条记录通过隐藏字段(如事务ID、回滚指针)链接多个版本,形成版本链。
    2. 事务根据版本链选择合适的可见版本。

示例

假设有一个账户表 accounts,初始记录如下:

img

场景

  • 事务A(ID=101):将余额从 1000 修改为 800。
  • 事务B(ID=102):在事务A提交前读取余额。

MVCC 处理流程

  1. 事务A修改数据时,生成新版本并记录 undo log(用于回滚):

img

  1. 事务B读取时,根据其快照时间点(如事务开始时),发现最新版本的事务ID=101尚未提交,因此通过回滚指针访问旧版本(balance=1000)。
  2. 事务A提交后,新版本生效,后续事务将读取到 balance=800。

MVCC 的优势

  1. 高并发
    1. 读写操作互不阻塞,适用于读多写少的场景(如电商、社交平台)。
  2. 避免锁竞争
    1. 读操作无需加锁,减少死锁风险和系统开销。
  3. 隔离性支持
    1. 通过版本控制实现不同隔离级别(如RC和RR)。

实现依赖

  1. Undo Log
    1. 存储数据旧版本,用于回滚和版本链回溯。
  2. Read View
    1. 事务启动时生成,记录当前活跃事务ID列表,用于判断数据版本的可见性。
  3. 隐藏字段
    1. DB_TRX_ID(最后修改该记录的事务ID)、DB_ROLL_PTR(指向旧版本的指针)。

隔离级别与 MVCC

  • 读已提交RC):
    • 每次读取生成新的 Read View,能看到其他事务已提交的最新数据。
  • 可重复读RR):
    • 事务首次读取时生成 Read View,后续读取沿用同一快照,保证多次读取结果一致(MySQL默认级别)。

MVCC 的局限性

  1. 存储开销
    1. 维护多版本需占用额外空间(undo log 和版本链)。
  2. 历史版本清理
    1. 需定期清理过期版本(如 MySQL 的 Purge 线程)。
  3. 写冲突
    1. 并发写仍需通过锁(如行锁)或乐观锁机制解决。

应用场景

  • 高并发查询系统(如新闻网站、实时数据分析)。
  • 需要支持快照读的业务(如金融对账、历史数据追溯)。

总结

MVCC 通过数据多版本化和快照读机制,在保证事务隔离性的同时大幅提升并发性能,是现代数据库(如 MySQL InnoDB、PostgreSQL)实现高并发的核心技术之一。