MySQL MVCC(多版本并发控制)详解
MVCC(Multi-Version Concurrency Control)是 MySQL InnoDB 存储引擎实现的一种并发控制机制,用于在保证事务隔离性的同时,提高数据库的并发性能。下面从原理、实现、事务隔离级别、优缺点和示例几个方面进行详细解析
MVCC 核心组件
1. 隐藏字段
每行记录包含三个隐藏字段:
列名 | 大小 | 描述 |
---|---|---|
DB_TRX_ID | 6字节 | 最近修改/插入该行的事务ID |
DB_ROLL_PTR | 7字节 | 回滚指针,指向Undo Log记录 |
DB_ROW_ID | 6字节 | 隐藏自增ID(无主键时使用) |
2. Undo Log(回滚日志)
3. Read View(读视图)
class ReadView {/* ... */
private:trx_id_t m_low_limit_id; /* 大于等于这个 ID 的事务均不可见 */trx_id_t m_up_limit_id; /* 小于这个 ID 的事务均可见 */trx_id_t m_creator_trx_id; /* 创建该 Read View 的事务ID */trx_id_t m_low_limit_no; /* 事务 Number, 小于该 Number 的 Undo Logs 均可以被 Purge */ids_t m_ids; /* 创建 Read View 时的活跃事务列表 */m_closed; /* 标记 Read View 是否 close */
}
MVCC工作流程
工作流程
数据修改流程
MVCC 与事务隔离级别的关系
1. READ COMMITTED(提交读)
特性 | 实现方式 |
---|---|
读视图创建时机 | 每次SELECT语句执行时创建新ReadView |
可见性 | 能看到最新提交的数据 |
2. REPEATABLE READ(可重复读)
特性 | 实现方式 |
---|---|
读视图创建时机 | 事务中第一次SELECT时创建ReadView |
可见性 | 整个事务看到相同的数据快照 |
幻读解决方案 | Next-Key Locking 机制 |
Read View 的可见性判断规则
当事务读取一行数据时,InnoDB 会根据以下规则判断该版本是否可见:
- 如果数据版本的 DB_TRX_ID < 事务的低水位:该版本在事务启动前已提交,可见。
- 如果数据版本的 DB_TRX_ID ≥ 事务的高水位:该版本在事务启动后才开始,不可见。
- 如果数据版本的 DB_TRX_ID 在事务的活跃列表中:该版本由一个活跃事务创建,不可见。
- 否则:该版本可见。
MVCC 的优缺点
1. 优点
高并发性能:读写不互斥,减少锁争用,提高吞吐量。
事务隔离:实现不同级别的事务隔离,保证数据一致性。
回滚高效:通过 undo 日志快速回滚。
快照读:支持一致性非锁定读,提高查询效率。
2. 缺点
存储空间开销:需要存储多个版本的数据和 undo 日志。
性能开销:维护 Read View 和版本链需要额外的 CPU 和内存资源。
长事务风险:长事务会保留大量 undo 日志,可能导致存储空间膨胀。