MySQL 的 MVCC(Multi-Version Concurrency Control,多版本并发控制)是 InnoDB 存储引擎实现隔离级别的核心机制,它通过保存数据的多个版本,允许读写操作不互相阻塞,从而提高数据库的并发性能。
MVCC 的核心思想
- 为每个数据行维护多个版本,不同事务在访问同一行数据时,可能看到不同的版本
- 读操作无需加锁(非锁定读),避免了传统锁机制中读阻塞写、写阻塞读的问题
- 通过版本号控制,实现事务的隔离性(主要支持
READ COMMITTED
和REPEATABLE READ
隔离级别)
实现关键技术
-
隐藏列
InnoDB 为每行数据添加了三个隐藏列:DB_TRX_ID
:记录最后一次修改该数据的事务 IDDB_ROLL_PTR
:回滚指针,指向该行数据的 undo log(撤销日志)DB_ROW_ID
:行标识(当表没有主键时自动生成)
-
Undo Log(撤销日志)
- 用于保存数据修改前的版本,形成版本链
- 事务回滚时,通过 undo log 恢复数据
- MVCC 通过遍历 undo log 链查找符合当前事务可见性的版本
-
Read View(读视图)
- 事务启动时生成的一个数据结构,用于判断数据版本的可见性
- 包含当前活跃事务的 ID 列表、最小活跃事务 ID、最大事务 ID 等信息
- 不同隔离级别生成 Read View 的时机不同:
READ COMMITTED
:每次查询时生成新的 Read ViewREPEATABLE READ
:事务启动时生成一次 Read View,后续查询复用
可见性判断规则
对于某个数据版本的 DB_TRX_ID
(修改事务 ID):
- 若小于 Read View 中的最小活跃事务 ID → 该版本可见
- 若大于等于 Read View 中的最大事务 ID → 该版本不可见
- 若在活跃事务 ID 列表中 → 该版本不可见(属于未提交事务修改)
- 若不在活跃事务 ID 列表中 → 该版本可见(属于已提交事务修改)
作用与优势
- 读写不冲突:读操作无需加锁,写操作只锁定必要的行
- 提高并发性能:多个事务可同时读写数据库,减少锁竞争
- 支持不同隔离级别:通过 Read View 生成时机的控制,实现
READ COMMITTED
和REPEATABLE READ
MVCC 是 InnoDB 实现高并发的关键,它与锁机制(如行锁、表锁)配合,共同保障了事务的 ACID 特性。