← 每日面试题 学习看板

如何理解MVCC?

面试题/03数据库中间件/01MySQL/02InnoDB核心原理(存储引擎-数据结构)/如何理解MVCC?.md

面试记录 2026-09-17

题目:如何理解 MVCC?

难度:medium

标签:db/mysql/innodb, mysql/innodb, difficulty/medium

评分:⭐⭐☆☆(2/5)

我的回答

MVCC 是在可重复读下的一个机制,它主要是用来控制,让不同的事务看到自己事务内的执行的内容,而不是看到其他事务,做到事务隔离的作用。它隔离的方式是通过版本控制,不同的事务来构成有自己各自的快照,看到自己当前版本下的快照的信息,而不会看到其他快照。

快照维护,我记得维护的数据信息是在哪个日志,具体没印象了。维护了包括当前的事务 ID,然后最大的活动的事务 ID,最小活动事务 ID,以及活动的事务 ID 的组。然后构建成它整个维护事务快照的一个数据。然后在它前面的事务,事务 ID 比它小的,它就不不去读,事务 ID 比它大的,事务 ID 比它小的它去读,事务 ID 比它大它不读。达到生成管控的不同事务间的隔离,进行版本并发控制。

点评

优点:

不足:

补充:

完整讲解

第一部分:知识重点剖析

核心考点定位:理解 MVCC 的数据结构基础(行版本 + undo 链)、ReadView 判定逻辑、以及它在隔离级别中的应用。

知识点拆解:

  1. MVCC 是什么:Multi-Version Concurrency Control,多版本并发控制。核心思想:读不阻塞写、写不阻塞读——通过给每行数据保留多个历史版本,让读事务看到自己需要的版本,而不是被锁阻塞。
  1. 底层数据结构:行隐藏字段

InnoDB 每行数据除了用户列外还有三个隐藏字段:

  1. undo log 版本链
  1. ReadView 是什么:事务读数据时创建的一个快照视图,包含四个关键字段:
  1. 可见性判定规则(关键,用户答反了):

给定一行数据的 DB_TRX_ID = trx_id,判断它对当前 ReadView 是否可见:

  1. RC 和 RR 的差别:ReadView 生成时机不同
  1. MVCC 只用于快照读
  1. MVCC 与幻读的关系
  1. MVCC 的代价

第二部分:考察方向与延伸递进

考察方向:

延伸递进面试题:

  1. 长事务为什么会导致 undo log 膨胀?
  1. SELECT FOR UPDATE 会走 MVCC 吗?
  1. RC 下为什么每次查询都新建 ReadView?为什么这就能读到其他事务的最新值?

第三部分:面试者参考回答(口语化)

面试官您好,MVCC 是 Multi-Version Concurrency Control,多版本并发控制,核心是让读和写互不阻塞。

底层结构有三部分:

第一是行的隐藏字段。InnoDB 每行数据除了用户列外还有三个隐藏字段:DB_TRX_ID 记录最后修改这行的事务 ID,DB_ROLL_PTR 是回滚指针,指向 undo log 里的上一个版本,DB_DELETE_MARK 是删除标记。

第二是 undo log 版本链。每次 UPDATE 都会生成一个新版本,同时把旧版本写入 undo log。反复 UPDATE 后一行数据就形成一条版本链:最新版本 → 上一版本 → 更早版本... 每次修改都往前挂一个版本。

第三是 ReadView。事务读数据时创建一个快照视图,里面有四个字段:m_ids 是当前还在活动的事务 ID 列表、min_trx_id 是 m_ids 里最小的、max_trx_id 是系统将要分配的下一个事务 ID、creator_trx_id 是创建者本身。

可见性判断是这样:拿一行数据的 trx_id 跟 ReadView 比:

如果当前版本不可见,就沿 DB_ROLL_PTR 找上一个版本继续判断,直到找到可见版本或者链尾。

RC 和 RR 的区别就是 ReadView 的生成时机不同。RC 每次 SELECT 都创建新的 ReadView,所以能看到其他事务提交后的最新值;RR 只在事务第一次 SELECT 时创建一次,事务期间一直复用,所以看不到其他事务期间提交的改动。这就是"RC 无法可重复读、RR 可以"的底层原因。

MVCC 只用于快照读,就是普通 SELECT。当前读——SELECT FOR UPDATE、UPDATE、DELETE——不走 MVCC,直接看最新的已提交版本,并通过锁保证一致性。

MVCC 还有个副作用要注意:undo log 链会随着版本累积变长。purge 线程会清理已无引用的旧版本,但长事务持有旧的 ReadView 会阻碍 purge,导致 undo log 膨胀。生产上要控制长事务的长度。