MVCC原理及数据库实现详解
MVCC(Multi-Version Concurrency Control,多版本并发控制)是数据库管理系统(如MySQL InnoDB、PostgreSQL、Oracle等)实现高并发访问的核心技术。它通过在读操作时不加锁来解决读写冲突,显著提升了数据库的并发性能。其核心思想是:为每个修改保留多个版本的数据,使得读操作可以访问特定版本的数据而不被写操作阻塞。
MVCC 核心原理
数据版本化存储
每次对数据进行修改(INSERT/UPDATE/DELETE)时,不直接覆盖原数据,而是创建该数据的一个新版本。
旧版本数据被保留在特定区域(如MySQL的
Undo Log
、PostgreSQL的Heap
)。每个数据版本关联两个关键字段:
创建事务ID(Create TXID):创建该版本的事务ID。
删除事务ID(Delete TXID):删除该版本的事务ID(初始为
NULL
)。事务快照(Snapshot)
事务启动时,会生成一个一致性视图(Read View),记录当前活跃事务ID列表。
通过快照确定哪些数据版本对该事务可见:
只显示在快照创建前已提交的数据版本。
忽略未提交或快照创建后提交的数据。
可见性判断规则
事务根据快照判断数据版本的可见性:
可见:数据版本的
Create TXID < 当前事务快照ID
且:Delete TXID = NULL
(未被删除),或Delete TXID > 当前事务快照ID
(在快照后被删除)。不可见:
Create TXID
属于活跃事务(未提交),或Create TXID > 当前事务快照ID
(在快照后创建),或Delete TXID < 当前事务快照ID
(在快照前已被删除)。
MVCC 在 MySQL InnoDB 中的实现
关键结构:
隐藏字段:
DB_TRX_ID
:最近修改该行的事务ID。DB_ROLL_PTR
:指向Undo Log中旧版本数据的指针。Undo Log:
存储历史版本数据,通过
DB_ROLL_PTR
形成版本链。Read View:
m_ids
:当前活跃事务ID集合。min_trx_id
:最小活跃事务ID。max_trx_id
:下一个将分配的事务ID。creator_trx_id
:创建该Read View的事务ID。
版本链示意图 ------------------- 当前行 | Data | TRX_ID=300 | ROLL_PTR → ------------------- | ↓ ------------------- Undo Log | Data_v2 | TRX_ID=200 | ROLL_PTR → ------------------- | ↓ ------------------- Undo Log | Data_v1 | TRX_ID=100 | ROLL_PTR=NULL -------------------
总结:
MVCC本质:通过保存数据历史版本,实现读操作的无锁访问。
关键机制:事务快照(Read View) + 版本链(通过Undo Log)。
适用场景:读多写少的高并发系统(如电商、社交应用)。
MySQL InnoDB:依赖Undo Log + Read View。