MySQL 中的 MVCC 是如何实现的?
MySQL 通过使用多版本控制来处理数据库的一致性问题。它利用回滚指针和事务快照来实现可重复读隔离级别,确保高并发下的数据一致性。
MVCC(Multi-Version Concurrency Control)是MySQL中InnoDB引擎用于支持可重复读(Repeatable Read)和读已提交(Read Committed)隔离级别的核心技术。其核心机制如下:
- 隐式字段:每条记录包含隐藏字段,存储事务元数据:
- DB_TRX_ID(6字节):记录最后修改事务的ID
- DB_ROLL_PTR(7字节):回滚指针,指向Undo Log的历史版本(即版本链)
- DB_ROW_ID(6字节):作为行唯一标识
- Undo Log(回滚日志):每次事务修改数据时:
- 将旧数据版本复制到Undo Log
- 串联形成版本链结构,DB_ROLL_PTR指向链表中前一版本
- Insert操作后Undo Log事务提交可立即删除;Update和Delete操作保留,支持快照读和回滚
- 版本链:通过DB_ROLL_PTR连接多个Undo Log记录的链表:
- 链表头部是最新数据,尾部为最初版本
- 用于追溯数据历史快照,访问事务开始时的版本
- Read View(一致性视图):事务快照读时创建的视图决定数据可见性:
- 组成元素:
- m_ids:当前活跃事务集合(未提交)
- min_trx_id:m_ids中最小事务ID
- max_trx_id:事务ID预分配最大值
- creator_trx_id:创建Read View的事务ID
- 可见性规则:
- 若行事务ID < min_trx_id,版本在Read View创建前提交,允许访问
- 若行事务ID ≥ max_trx_id,版本在Read View后创建,禁止访问
- 若行事务ID = creator_trx_id,版本由当前事务修改,允许访问
- 若行事务ID在m_ids中,版本来自未提交事务,禁止访问
- 组成元素:
- 依赖隔离级别的工作流程:
- Repeatable Read级别仅初始化时创建一次Read View
- Read Committed级别每次SELECT重新生成Read View
- MVCC只控制快照读,确保读取一致;当前读(如SELECT FOR UPDATE,INSERT)仍需加锁
关键优势:非锁定读写提高并发性能,优化冲突管理