1. 为什么需要了解MVCC?
在数据库系统中,事务隔离性是一个核心特性。想象一下,当多个用户同时操作数据库时,如果没有合适的并发控制机制,就会出现各种问题:一个事务可能读到另一个未提交事务修改的数据(脏读),或者同一个事务内两次查询结果不一致(不可重复读),甚至发现其他事务新增的数据(幻读)。
MVCC(Multi-Version Concurrency Control,多版本并发控制)就是InnoDB存储引擎用来解决这些问题的一种机制。与传统的锁机制不同,MVCC通过创建数据行的多个版本来实现并发控制,使得读操作不会被写操作阻塞,写操作也不会被读操作阻塞。
提示:MVCC并不是MySQL独有的概念,PostgreSQL等数据库也实现了各自的MVCC机制,但具体实现方式有所不同。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. MVCC的核心实现原理
2.1 版本链与隐藏字段
InnoDB的每行记录实际上都包含三个隐藏字段:
- DB_TRX_ID:6字节,记录最近一次修改该行记录的事务ID
- DB_ROLL_PTR:7字节,回滚指针,指向该行的undo log记录
- DB_ROW_ID:6字节,隐藏的自增ID(当表没有主键时作为聚簇索引的键值)
这些隐藏字段共同构成了MVCC的版本链基础。当一个事务修改某行数据时:
- 会先将该行数据拷贝到undo log中
- 然后修改当前行的数据,并更新DB_TRX_ID和DB_ROLL_PTR字段
- DB_ROLL_PTR指向undo log中的旧版本记录
2.2 ReadView机制
ReadView是MVCC实现快照读的关键数据结构,它定义了事务在某个时间点能看到哪些版本的数据。ReadView包含四个重要信息:
- m_ids:生成ReadView时活跃的事务ID列表
- min_trx_id:m_ids中的最小值
- max_trx_id:生成ReadView时InnoDB将分配给下一个事务的ID
- creator_trx_id:创建该ReadView的事务ID
判断一个数据版本是否对当前事务可见的规则如下:
- 如果数据版本的DB_TRX_ID等于creator_trx_id,说明是本事务修改的,可见
- 如果DB_TRX_ID小于min_trx_id,说明该版本在ReadView创建
