MVCC是一种并发控制机制,用于在多个并发事务同时读取和写入数据库时保持数据的一致性和隔离性。其核心思想是通过维护每个数据行的多个版本来实现。
Innodb的实现
隐藏字段
- DB_TRX_ID(6字节): 当前事务的ID。
- DB_ROLL_PTR(7字节): 指向上一个事务的ID,指向上一个undo log。
- DB_ROW_ID(6字节): 非空索引,仅在数据没有主键时使用。
ReadView
- 最大事务ID + 1: 大于这个版本的事务不可见。
- 最小事务ID: 小于这个的事务可见。
- 当前的事务ID: 标识当前事务。
- 活跃事务ID集合: 包含所有活跃事务的ID,若存在则不可见。
m_ids
不包括当前事务自己和已提交的事务。
Undo Log(回滚日志)
在读取记录时,如果该记录被其他事务占用或当前版本对该事务不可见,可以通过undo log读取之前的版本数据,从而实现非锁定读。
数据可见性算法
数据可见性是通过比较隐藏字段的DB_TRX_ID
(本次事务的ID)和ReadView中的各个字段来判断数据是否可见。
RC和RR下MVCC的差异
-
RC(读已提交)隔离级别:
- 每次
SELECT
查询前生成一个新的Read View(m_ids
列表)。
- 每次
-
RR(可重复读)隔离级别:
- 只在事务开始后第一次
SELECT
数据前生成一个Read View(m_ids
列表)。
- 只在事务开始后第一次
总结
MVCC通过版本控制和回滚日志机制有效地解决了并发事务之间的数据一致性和隔离性问题。不同的隔离级别(RC和RR)在Read View的生成时机上有所不同,从而影响了数据的可见性和并发性能。