目录一、MVCC 多版本并发控制1. 作用2. 核心隐藏字段每条行记录自带3. Undo Log 版本链4. Read View 读视图RR 隔离核心可见性规则遍历版本链判断5. RC vs RR 的 MVCC 区别6. MVCC 解决了什么问题二、InnoDB 锁体系 间隙锁Gap Lock1. 三类锁组合RR 下当前读生效2. 间隙锁什么时候产生3. 锁范围规则基于索引无索引退化成表锁场景 1命中唯一索引精准匹配一条完整记录场景 2范围查询 / 不命中任何索引值 / 普通索引模糊匹配场景 3查询条件无索引4. 间隙锁特点5. 插入意向锁Gap Intention Lock三、MVCC 和 间隙锁分工对比重点区分关键一句话总结四、高频面试延伸考点默认前提InnoDB 引擎、事务隔离级别 RR可重复读MySQL 默认这两个机制都是 InnoDB 实现并发控制、解决幻读的核心。一、MVCC 多版本并发控制1. 作用不用加锁实现读写互不阻塞读不加锁、写加排他锁大幅提升并发性能同时实现 RR 隔离。快照读普通 select走 MVCC无锁当前读update/delete/select ... for update走行锁 间隙锁阻塞写2. 核心隐藏字段每条行记录自带DB_TRX_ID最近修改该行的事务 IDDB_ROLL_PTR回滚指针指向 undo log版本链DB_ROW_ID无主键时隐藏主键3. Undo Log 版本链每次修改数据不会直接覆盖原数据而是把旧版本存入 undo log通过roll_ptr串联成版本链表。 一条记录的多个历史版本构成一条版本链。4. Read View 读视图RR 隔离核心事务执行第一次快照读时生成用来判断当前版本是否可见4 个关键字段m_ids当前活跃未提交事务集合min_trx_id活跃事务最小 IDmax_trx_id下一个待分配事务 IDcreator_trx_id当前事务自己 ID可见性规则遍历版本链判断拿版本的trx_id和 ReadView 对比trx_id creator_trx_id自己改的数据可见trx_id min_trx_id事务已提交可见trx_id max_trx_id事务启动晚于当前视图不可见min_trx_id ≤ trx_id ≤ max_trx_idtrx_id 在 m_ids 活跃集合未提交不可见不在 m_ids已提交可见不满足就顺着 roll_ptr 找上一个历史版本直到找到可见版本。5. RC vs RR 的 MVCC 区别RC读已提交每次 select 都生成新 ReadView能看到其他事务已提交数据会出现不可重复读无间隙锁会幻读。RR可重复读一个事务内只生成一次 ReadView全程复用解决不可重复读配合间隙锁解决幻读。6. MVCC 解决了什么问题快照读下解决脏读、不可重复读快照读不会阻塞写写也不会阻塞快照读但 MVCC 无法解决当前读的幻读幻读靠「间隙锁」解决。二、InnoDB 锁体系 间隙锁Gap Lock1. 三类锁组合RR 下当前读生效记录锁 Record Lock锁住索引上存在的某一行间隙锁 Gap Lock锁住索引记录之间的空隙阻止插入新数据专门防幻读临键锁 Next-Key Lock Record GapRR 默认加的锁左开右闭区间(a,b]幻读定义同一事务内多次当前读中间其他事务插入新数据第二次读多出数据。间隙锁锁空隙不让别的事务插入彻底杜绝幻读。2. 间隙锁什么时候产生仅满足两个条件隔离级别 RRRC 无间隙锁只会出现幻读当前读update / delete / select ... for update / lock in share mode3. 锁范围规则基于索引无索引退化成表锁场景 1命中唯一索引精准匹配一条完整记录临键锁降级为记录锁不再加间隙锁 例主键 id10select * from t where id10 for update;只锁 id10 这一行不锁间隙其他事务可以插入 9、11。场景 2范围查询 / 不命中任何索引值 / 普通索引模糊匹配加临键锁Next-Key包含间隙阻止插入 示例表主键1,3,5,7 执行where id 5 for update锁定区间(-∞,1], (1,3], (3,5]间隙(0,1)、(1,3)、(3,5)全部锁住其他事务不能插入 2、4杜绝幻读。场景 3查询条件无索引无法定位行直接升级为表级临键锁整张表所有间隙全部锁住并发极差。4. 间隙锁特点共享 / 排他间隙锁冲突规则间隙锁之间互不阻塞事务 A 加间隙锁 (3,5)事务 B 也可以加 (3,5) 间隙锁只有插入操作会被间隙锁阻塞插入意向锁冲突。只存在 RR 隔离级别RC 全程没有间隙锁允许幻读。锁的是索引间隙不是物理数据页。5. 插入意向锁Gap Intention Lock事务要插入数据时先加插入意向间隙锁表示 “我准备在这个间隙插入”。 如果该区间已有普通间隙锁插入意向锁等待阻塞实现间隙锁阻止插入的效果。三、MVCC 和 间隙锁分工对比重点区分维度MVCC间隙锁临键锁作用对象快照读普通 select当前读update/for update解决问题脏读、不可重复读当前读下的幻读并发表现读写不阻塞写之间互相阻塞锁机制无锁靠 undo 版本链悲观锁锁定索引间隙RC 下是否存在存在不存在RR 下是否存在存在存在关键一句话总结MVCC 负责普通查询不加锁保证快照读稳定可重复间隙锁临键锁负责写操作时锁住空隙防止其他事务插入新数据解决当前读幻读两者配合让 InnoDB 在 RR 隔离下既拥有高并发又完美满足可重复读、无幻读。四、高频面试延伸考点为什么 RR 能解决幻读RC 不行 RC 没有间隙锁范围更新时其他事务可以插入新行出现幻读RR 当前读加临键锁锁住间隙禁止插入。唯一索引等值查询为什么间隙锁会降级 唯一索引精准匹配只会命中一条记录不存在新增插入产生幻读的可能无需锁间隙只加记录锁提升并发。MVCC 是乐观锁还是悲观锁 MVCC 是乐观并发控制行锁 / 间隙锁属于悲观锁两套机制独立工作。undo log 什么时候清理 没有任何事务需要访问该历史版本时purge 线程后台清理。