MVCC(Multi-Version Concurrency Control,多版本并发控制)是一种通过保存数据多个版本来实现高并发、非阻塞读的机制,广泛用于 MySQL(InnoDB)、PostgreSQL 等数据库。下面我用原理 + InnoDB 示例 + 事务流程来说明 MVCC 在事务中是如何工作的。
读不加锁,写不阻塞读
MVCC 的核心思想是:
InnoDB 的聚簇索引记录中,除了你定义的列,还有:
| 字段 | 含义 |
|---|---|
DB_TRX_ID |
最后修改该行的事务 ID |
DB_ROLL_PTR |
回滚指针,指向 undo log |
DB_ROW_ID |
行 ID(无主键时自动生成) |
roll_ptr 指向旧版本roll_ptr 形成版本链最新版本 → 旧版本 → 更旧版本 → ... → undo log
事务在第一次读时生成 Read View(RC 每次读,RR 第一次读)
Read View 包含:
m_ids:当前活跃事务 ID 列表min_trx_id:最小活跃事务 IDmax_trx_id:下一个将被分配的事务 IDcreator_trx_id:当前事务 ID对于某行记录的 DB_TRX_ID:
m_ids 中 → ❌ 活跃事务,不可见如果当前版本不可见 → 沿 undo log 找上一个版本,继续判断。
CREATE TABLE account (
id INT PRIMARY KEY,
balance INT
);
| id | balance |
|---|---|
| 1 | 100 |
START TRANSACTION;
SELECT * FROM account WHERE id = 1;
START TRANSACTION;
UPDATE account SET balance = 200 WHERE id = 1;
COMMIT;
SELECT * FROM account WHERE id = 1;
✅ 可重复读(RR)
| 隔离级别 | Read View 创建时机 |
|---|---|
| READ COMMITTED | 每次 SELECT 创建 |
| REPEATABLE READ | 事务中第一次 SELECT 创建 |
所以:
MVCC 通过 undo log 保存历史版本,通过 Read View 判断版本可见性,让事务在不加锁的情况下读到一致性数据。
如果你愿意,我可以:
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。