MySQL 系统学习 第四阶段:MySQL 高级 第六节:MVCC(Multi-Version Concurrency Control,多版本并发控制)

📅 2026/7/14 5:17:43
MySQL 系统学习 第四阶段:MySQL 高级 第六节:MVCC(Multi-Version Concurrency Control,多版本并发控制)
前面我们学习事务保证一组操作的一致性锁解决多个事务同时修改数据的问题但是有一个问题如果所有查询都加锁数据库还能高并发吗答案不能。所以 InnoDB 引入了MVCC让读操作不需要加锁也能读取一致的数据版本。一、为什么需要 MVCC假设用户表id | name | age 1 | Tom | 20现在两个事务事务A查询SELECT * FROM user WHERE id1;事务B修改UPDATE user SET age21 WHERE id1;如果没有 MVCC事务A读取时必须等待事务B完成。结果并发能力下降。有 MVCC事务A读取旧版本age20事务B修改新版本age21两个事务互不影响。二、MVCC 的核心思想一句话数据库保存数据的多个版本读取时根据事务规则选择合适版本。例如数据版本1 age20 版本2 age21 版本3 age22不同事务看到不同版本。类似 Gitcommit1 | commit2 | commit3可以查看不同历史版本。三、InnoDB 实现 MVCC 依赖什么主要依靠三个东西1. 隐藏字段2. Undo Log回滚日志3. Read View读视图⭐⭐⭐⭐⭐四、隐藏字段InnoDB 每一行数据实际上有隐藏字段。例如用户表CREATE TABLE user( id INT, name VARCHAR(20) );实际上InnoDB 保存类似id name 隐藏字段 ---------------- DB_TRX_ID DB_ROLL_PTR① DB_TRX_ID事务ID。表示哪个事务修改了这条数据。例如事务100修改 DB_TRX_ID100② DB_ROLL_PTR回滚指针。指向上一个版本的数据。形成版本链。五、Undo Log回滚日志Undo Log作用保存数据修改之前的版本。例如原数据age20事务A修改UPDATE user SET age21;数据库保存Undo Logage20现在当前数据age21历史数据age20形成当前版本 | | Undo Log | 旧版本六、版本链是什么例如数据不断修改第一次age20事务101age21事务102age22最终age22 ↓ age21 ↓ age20这就是版本链。七、Read View读视图⭐⭐⭐⭐⭐这是 MVCC 最核心概念。Read View事务进行普通查询时创建的一份可见性规则。简单理解它决定我应该看到哪个版本的数据。例如当前数据版本3 | 版本2 | 版本1事务A创建 Read View。规则可能看到版本2而不是最新版本3八、MVCC 如何判断数据是否可见InnoDB 会比较数据版本中的DB_TRX_ID和当前事务的 Read View。简单理解如果修改数据的事务已经提交可以看到。如果修改数据的事务还没有提交不能看到。九、MVCC 解决什么问题主要解决1. 读写冲突例如事务A读取。事务B修改。不用互相等待。2. 提高并发传统方式读 | 加锁 | 等待写MVCC读 | 读取历史版本十、MVCC 与隔离级别关系MySQL InnoDB 默认REPEATABLE READ可重复读。为什么可以做到因为MVCC。例如事务A第一次查询余额1000事务B修改余额500提交。事务A再次查询仍然余额1000因为使用同一个 Read View。十一、MVCC 如何解决不可重复读不可重复读原因第二次读取看到最新数据。MVCC第一次查询创建 Read View看到版本1第二次查询继续使用版本1所以结果一致。十二、MVCC 和锁的区别很多人容易混淆。MVCC锁解决问题读一致性并发修改冲突方式版本控制阻塞等待是否阻塞通常不阻塞可能阻塞主要对象读操作写操作例如普通查询SELECT * FROM user;使用MVCC。修改UPDATE user SET age20;使用锁。十三、普通 SELECT 和 FOR UPDATE 区别普通查询SELECT * FROM user WHERE id1;特点不加锁使用 MVCC读取快照数据当前读SELECT * FROM user WHERE id1 FOR UPDATE;特点加锁读取最新数据用于修改前查询例如库存扣减必须SELECT stock FROM product WHERE id1 FOR UPDATE;不能使用普通 SELECT。十四、企业开发中的应用场景1订单查询普通SELECT * FROM orders WHERE user_id100;使用MVCC。高并发没问题。场景2库存修改需要SELECT stock FROM product WHERE id1 FOR UPDATE;使用锁。保证不会超卖。十五、本节总结概念作用MVCC多版本并发控制目的提高数据库并发能力Undo Log保存历史版本版本链保存数据变化记录Read View判断版本是否可见普通SELECT使用MVCCFOR UPDATE使用锁RR隔离级别依赖MVCC实现可重复读 本节核心一句话MVCC 通过保存数据历史版本让读操作不需要加锁也能看到一致的数据是 InnoDB 高并发能力的核心机制。