MySql MVCC的原理总结
MySQL MVCC 原理详解
MVCC (Multi-Version Concurrency Control,多版本并发控制) 是 MySQL 实现并发访问控制的核心机制之一,主要应用于 InnoDB 存储引擎。
一、MVCC 基本概念
MVCC 是一种通过保存数据在某个时间点的快照来实现并发控制的方法。它使得不同事务在同一时间看到的数据版本可能不同,从而避免了读取操作被写入操作阻塞。
二、MVCC 核心组件
1. 隐藏字段
InnoDB 每行记录都包含几个隐藏字段:
DB_TRX_ID
:6字节,记录最近修改该行数据的事务IDDB_ROLL_PTR
:7字节,指向该行回滚段的指针(即指向undo log)DB_ROW_ID
:6字节,隐藏的自增ID(当没有主键时生成)
2. Undo Log
存储数据被修改前的值,用于:
- 事务回滚
- 实现MVCC,提供历史版本数据
3. Read View
事务进行快照读时产生的读视图,包含:
trx_ids
:当前活跃(未提交)事务ID列表low_limit_id
:创建ReadView时系统应该分配给下一个事务的IDup_limit_id
:活跃事务列表中最小的事务IDcreator_trx_id
:创建该ReadView的事务ID
三、MVCC 实现原理
1. 版本链
每行记录通过 DB_ROLL_PTR
指向 undo log 形成一个版本链,可以回溯到该记录的所有历史版本。
2. 可见性判断规则
判断记录某个版本是否对当前事务可见:
- 如果
DB_TRX_ID
==creator_trx_id
:当前事务修改的记录,可见 - 如果
DB_TRX_ID
<up_limit_id
:该版本在ReadView创建前已提交,可见 - 如果
DB_TRX_ID
>=low_limit_id
:该版本在ReadView创建后产生,不可见 - 如果
up_limit_id
<=DB_TRX_ID
<low_limit_id
:- 如果
DB_TRX_ID
在trx_ids
列表中:未提交,不可见 - 否则:已提交,可见
- 如果
3. 不同隔离级别的实现
- READ COMMITTED:每次读取都生成新的ReadView
- REPEATABLE READ:第一次读取时生成ReadView,后续复用
四、MVCC 操作示例
插入操作
- 分配事务ID
- 写入数据,设置
DB_TRX_ID
为当前事务ID DB_ROLL_PTR
指向 undo log 中的插入记录
更新操作
- 分配事务ID
- 将当前记录拷贝到 undo log
- 修改当前记录,更新
DB_TRX_ID
和DB_ROLL_PTR
删除操作
- 分配事务ID
- 将当前记录拷贝到 undo log
- 设置记录的删除标志位
五、MVCC 优缺点
优点:
- 读不加锁,读写不冲突
- 提高了并发性能
- 实现了非阻塞读
缺点:
- 需要维护多个版本,增加了存储空间
- 需要定期清理不再需要的版本数据
- 写操作仍然需要加锁
六、MVCC 与 Purge 机制
InnoDB 通过 Purge 线程清理不再需要的 undo log:
- 当没有事务需要访问这些旧版本时
- 系统表空间中记录最老的ReadView,确定哪些版本可以清理
MVCC 是 MySQL 实现高并发的重要机制,理解其原理对于优化数据库性能和解决并发问题非常有帮助。