

一、为什么需要MVCC?
在MVCC出现之前,数据库并发控制主要依靠锁机制:
读读共享:多个读操作可以同时进行
读写互斥:写操作会阻塞读操作
写写互斥:写操作会相互阻塞
这种方式虽然保证了数据一致性,但效率低下——就像一个事务在缓慢地写入数据时,所有想要读取的数据的事务都必须在门外排队等待。
MVCC的出现,正是为了实现"读写不冲突"的理想状态:写事务修改数据的同时,读事务可以不受影响地读取数据的历史版本,二者互不干扰。
二、核心机制:版本链与隐藏字段
MVCC的核心思想是:"我不看你现在变成什么样了,我只读取我该看到的那个版本。"
为了实现这一点,InnoDB为每一行数据隐式地添加了两个关键字段:
| 字段名 | 说明 | 类比 |
| DB_TRX_ID | 最近一次修改该行数据的事务ID | 数据行的"签名者" |
| DB_ROLL_PTR | 回滚指针,指向该行数据的上一个版本 | 通往历史版本的"传送门" |
版本链的形成:
1.当修改数据时,InnoDB并不直接覆盖原有数据
2.而是将旧版本数据存入UndoLog(回滚日志)
3.通过DB_ROLL_PTR将各个版本按修改时间逆序连接,形成一条"版本链"
三、可见性算法:MVCC的灵魂所在
很多开发者知道"快照读"的概念,但面试中最常被追问的是:"数据库如何判断某个版本对当前事务是否可见?"
答案在于ReadView(一致性视图)机制。当事务执行快照读时,InnoDB会为其生成一个ReadView,其中包含四个关键信息:
m_ids:当前系统中所有活跃(未提交)事务的ID列表
min_trx_id:m_ids中的最小值
max_trx_id:系统即将分配给下一个事务的ID
creator_trx_id:创建此ReadView的事务自身的ID
可见性判断流程(按版本链从新到旧遍历):
当检查版本链中某个版本(假设其事务ID为`trx_id`)时,按以下规则判断:
```python
简化版可见性判断逻辑
defis_version_visible(trx_id,read_view):
1.是否是自己修改的?
iftrx_id==read_view.creator_trx_id:
returnTrue自己修改的总是可见
2.是否是"过去"的事务?
iftrx_id<read_view.min_trx_id:
returnTrue在当前事务开始前就已提交
3.是否是"未来"的事务?
iftrx_id>=read_view.max_trx_id:
returnFalse在当前事务开始后才启动
4.是否是"正在进行中"的事务?
iftrx_idinread_view.m_ids:
returnFalse尚未提交,不可见
else:
returnTrue已提交,可见
```
查找过程:
1.从版本链的最新版本开始检查
2.如果当前版本对事务不可见,则通过DB_ROLL_PTR指针找到上一个版本
3.重复上述判断,直到找到第一个对当前事务可见的版本为止
四、RC与RR隔离级别的区别
问题的核心:为什么ReadCommitted(读已提交)级别下会出现"不可重复读",而RepeatableRead(可重复读)级别下可以避免?
根本区别在于ReadView的生成时机:
| 隔离级别 | ReadView生成时机 | 类比 | 效果 |
| RC(读已提交) | 每次执行SELECT时都会生成新的ReadView | 每次睁开眼睛都重新拍一张照片 | 能看到其他事务已提交的最新数据,导致不可重复读 |
| RR(可重复读) | 只在第一次执行SELECT时生成ReadView,后续读取都复用这个视图 | 只在事务开始时拍一张照片,之后都看这张照片 | 无论其他事务如何修改数据,看到的始终是事务开始时的数据状态 |
五、MVCC的总结与思考
MVCC的优势:
1.高并发:读操作不加锁,读写操作不冲突,极大提升并发性能
2.一致性:为每个事务提供一致的数据视图
3.回滚支持:通过版本链天然支持事务回滚
MVCC的代价:
1.存储开销:需要额外空间存储UndoLog和版本信息
2.性能开销:查询时需要遍历版本链,计算可见性
3.清理成本:需要定期清理不再需要的旧版本数据
进阶思考:
虽然MVCC在RR隔离级别下解决了不可重复读问题,也能避免部分幻读现象,但在某些特定场景下(如"先查询,后基于查询结果更新"),仍然可能出现幻读。这时需要配合NextKeyLock(间隙锁)机制来提供更严格的并发控制。
六、形象总结
MVCC如同一个精密的时空穿梭机:
通过版本链保存数据的历史状态
通过ReadView为每个事务定格特定的时间画面
在繁忙的数据库世界中为每个事务开辟一条安静的"时光隧道"
它让数据库在保证数据一致性的同时,实现了读写并发的高性能,是现代关系型数据库高并发能力的核心技术基石。

一家致力于优质服务的软件公司
8年互联网行业经验1000+合作客户2000+上线项目60+服务地区

关注微信公众号
