概述
MVCC,全称 Multi-Version Concurrency Control,即多版本并发控制。它是一种为了提高数据库并发性能而提出的技术,使得在并发读写数据库时,读操作不会阻塞写操作,写操作也不会阻塞读操作。这就解决了传统的锁机制带来的性能瓶颈问题。
MySQL 中,InnoDB 存储引擎实现了 MVCC。
一、MVCC 要解决的核心问题
在没有 MVCC 的情况下,如果我们要保证事务的隔离性(例如可重复读级别),通常会用锁来实现。当一个事务正在读取某些数据时,其他事务就不能修改这些数据(共享锁),这会导致'读 - 写'冲突;同样,一个事务在修改数据时(排他锁),其他事务也不能读取,这会导致'写 - 读'冲突。MVCC 通过创建数据的历史版本来优雅地解决这个问题。
核心思想: 为每行数据维护多个历史版本。当一个事务需要读取数据时,它会看到在它开始之前就已经提交的某个一致性数据快照,而不管当前这些数据被其他事务修改成了什么样子。
二、MVCC 的实现基石
MVCC 的实现依赖于三个核心组件:
- 隐藏字段
- Undo Log
- Read View(读视图)
下面我们逐一详解。
1. 隐藏字段
InnoDB 为每一行数据(记录)都添加了三个系统隐藏字段:

DB_TRX_ID(6 字节):事务 ID。表示最后一次插入或更新该行的事务 ID。此外,删除在内部也被视为更新,会在该行数据中设置一个特殊的删除标记。DB_ROLL_PTR(7 字节):回滚指针。指向该行数据的上一个历史版本,存储在 Undo Log 中。DB_ROW_ID(6 字节):行 ID。随着新行插入而单调递增的行 ID。如果表没有定义主键,InnoDB 会基于这个字段生成一个聚簇索引。
注意: 实际上还有一个删除标记的隐藏字段,用于标记该行是否被删除。
2. Undo Log

Undo Log(回滚日志)主要有两个作用:
- 事务回滚时,用于恢复数据。
- 实现 MVCC 的关键。它存储了数据行的历史版本。
工作原理: 当一个事务对某行数据进行修改(INSERT, UPDATE, DELETE)时:
- UPDATE / DELETE: 会先将该行数据的当前版本(修改前)复制到 Undo Log 中。这个副本中包含了
DB_TRX_ID和DB_ROLL_PTR。新的DB_ROLL_PTR会指向这个刚刚存入 Undo Log 的旧版本。然后才在表中修改该行数据,写入新的DB_TRX_ID和新的DB_ROLL_PTR。 - INSERT: 因为新插入的数据对之前的事务不可见,所以它的 Undo Log 只在事务回滚时需要,在 MVCC 中作用不大。






