外观
什么是MVCC
⭐ 题目日期:
小红书 - 2024/11/11
📝 题解:
MVCC(Multi-Version Concurrency Control) 是一种数据库并发控制技术,通过维护数据的多个版本来实现高并发的读写操作,避免传统锁机制带来的性能瓶颈。其核心思想是:每个事务看到的数据版本独立,读操作不阻塞写操作,写操作也不阻塞读操作。
核心原理
- 数据版本化:
- 每次对数据的修改(增删改)会生成一个新版本,旧版本保留在数据库中(通过 undo log 或时间戳标记)。
- 不同事务根据其启动时间或隔离级别,访问对应的数据版本。
- 快照读(Snapshot Read):
- 事务读取数据时,基于某个时间点的快照(如事务开始时的数据版本),而非最新数据。
- 读操作不会因其他事务的写操作而阻塞。
- 版本链管理:
- 每条记录通过隐藏字段(如事务ID、回滚指针)链接多个版本,形成版本链。
- 事务根据版本链选择合适的可见版本。
示例
假设有一个账户表 accounts
,初始记录如下:
场景:
- 事务A(ID=101):将余额从 1000 修改为 800。
- 事务B(ID=102):在事务A提交前读取余额。
MVCC 处理流程:
- 事务A修改数据时,生成新版本并记录 undo log(用于回滚):
- 事务B读取时,根据其快照时间点(如事务开始时),发现最新版本的事务ID=101尚未提交,因此通过回滚指针访问旧版本(balance=1000)。
- 事务A提交后,新版本生效,后续事务将读取到 balance=800。
MVCC 的优势
- 高并发:
- 读写操作互不阻塞,适用于读多写少的场景(如电商、社交平台)。
- 避免锁竞争:
- 读操作无需加锁,减少死锁风险和系统开销。
- 隔离性支持:
- 通过版本控制实现不同隔离级别(如RC和RR)。
实现依赖
- Undo Log:
- 存储数据旧版本,用于回滚和版本链回溯。
- Read View:
- 事务启动时生成,记录当前活跃事务ID列表,用于判断数据版本的可见性。
- 隐藏字段:
- 如
DB_TRX_ID
(最后修改该记录的事务ID)、DB_ROLL_PTR
(指向旧版本的指针)。
- 如
隔离级别与 MVCC
- 读已提交(RC):
- 每次读取生成新的 Read View,能看到其他事务已提交的最新数据。
- 可重复读(RR):
- 事务首次读取时生成 Read View,后续读取沿用同一快照,保证多次读取结果一致(MySQL默认级别)。
MVCC 的局限性
- 存储开销:
- 维护多版本需占用额外空间(undo log 和版本链)。
- 历史版本清理:
- 需定期清理过期版本(如 MySQL 的 Purge 线程)。
- 写冲突:
- 并发写仍需通过锁(如行锁)或乐观锁机制解决。
应用场景
- 高并发查询系统(如新闻网站、实时数据分析)。
- 需要支持快照读的业务(如金融对账、历史数据追溯)。
总结
MVCC 通过数据多版本化和快照读机制,在保证事务隔离性的同时大幅提升并发性能,是现代数据库(如 MySQL InnoDB、PostgreSQL)实现高并发的核心技术之一。