MVCC(Multi-Version Concurrency Control,多版本并发控制)是现代数据库(如 MySQL InnoDB、PostgreSQL、Oracle 等)用来实现高并发读写而不互相阻塞的核心机制。其关键在于:为每个事务提供数据在某个时间点的“快照”,并通过可见性规则判断哪些版本对当前事务可见。
下面以 MySQL InnoDB 为例,系统说明 MVCC 的可见性规则(其他数据库原理类似,但细节略有差异)。
DB_TRX_ID:最后一次修改该行的事务 IDDB_ROLL_PTR:回滚指针,指向 Undo Log 中的旧版本DB_ROW_ID(可选):行 ID在快照读(普通 SELECT)时生成,包含:
m_ids:当前活跃(未提交)的事务 ID 列表min_trx_id:活跃事务中最小 IDmax_trx_id:下一个将分配的事务 IDcreator_trx_id:创建该 ReadView 的事务 ID当某事务读取一行数据时,会按以下规则判断该版本是否可见:
DB_TRX_ID == creator_trx_id
→ 自己改的,当然能看到
DB_TRX_ID < min_trx_id
→ 在 ReadView 创建前就已提交,可见
DB_TRX_ID >= max_trx_id
→ 当前事务“出生前”的未来事务,不可见
min_trx_id <= DB_TRX_ID < max_trx_id
且 DB_TRX_ID 在 m_ids 中
→ 修改数据的事务还没提交,不可见
DB_TRX_ID 不在 m_ids 中
→ 虽然 ID 在区间内,但已提交,可见
如果当前版本不可见:
DB_ROLL_PTR 找 Undo Log 中的旧版本| 隔离级别 | ReadView 生成时机 | 可见性特点 |
|---|---|---|
| READ UNCOMMITTED | 无 MVCC | 读最新,可能脏读 |
| READ COMMITTED | 每次 SELECT 都生成 | 避免脏读 |
| REPEATABLE READ(MySQL 默认) | 第一次 SELECT 生成 | 避免不可重复读 |
| SERIALIZABLE | 退化成锁 | 无 MVCC |
MVCC 可见性规则的本质是:只让事务看到“在它视角下已经提交的数据版本”,并通过事务 ID 和 ReadView 来判断版本是否合法。
如果你愿意,我也可以:
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。