大家好我是程序员二叉。一、简介MVCC多版本并发控制是 MySQL InnoDB 引擎的核心机制也是后端面试高频考点。它可以无锁实现读写并发解决读写互相阻塞的性能问题同时支撑了 MySQL 两大事务隔离级别读已提交RC、可重复读RR。本文全面拆解 MVCC 底层原理包含快照读与当前读、行隐式字段、undo log 与版本链、ReadView 视图、隔离级别实现等内容适合学习与面试背诵欢迎点赞收藏关注。二、MVCC 核心概述MVCC 全称Multi-Version Concurrency Control多版本并发控制仅针对 InnoDB 存储引擎生效。核心作用实现无锁读读写互不阻塞大幅提升数据库并发能力依靠数据多版本机制规避脏读、不可重复读实现不同事务隔离级别。MVCC 三大核心要素行隐式字段 undo log 版本链 ReadView 读视图。三、两种读取模式快照读 当前读InnoDB 的读操作分为两类是理解 MVCC 的基础二者核心区别读取历史快照数据 / 读取最新实时数据。1. 快照读Snapshot Read定义无锁读取读取事务快照中的历史版本数据读写互不阻塞并发性能高。触发语句普通无锁SELECT查询。-- 典型快照读SELECT*FROMuserWHEREid1;举例可重复读级别事务 A 开启事务首次查询 id1结果为 name张三事务 B 修改数据为 name李四并提交事务事务 A 再次执行相同查询依旧读到 name张三。原理事务 A 读取的是事务启动时的快照数据并非数据库最新数据。2. 当前读Current Read定义加锁读取强制读取数据库最新已提交数据属于悲观锁机制会产生锁阻塞。触发语句所有增删改操作、加锁查询均为当前读。-- 加锁查询当前读SELECT*FROMuserWHEREid1FORUPDATE;SELECT*FROMuserWHEREid1LOCKINSHAREMODE;-- 写入操作底层都是当前读UPDATEuserSETname李四WHEREid1;DELETEFROMuserWHEREid1;举例事务 A 执行 FOR UPDATE 加锁查询无论其他事务是否修改提交数据始终读取最新数据。四、InnoDB 行三大隐式字段InnoDB 会为每一行数据自动添加 3 个隐藏字段是 MVCC 实现的底层数据支撑。隐式字段名占用字节核心作用DB_TRX_ID6记录最后修改当前行的事务 ID增 / 改 / 删都会更新标记数据版本归属是可见性判断依据DB_ROLL_PTR7回滚指针指向 undo log 中上一个历史版本串联所有版本形成版本链DB_ROW_ID8隐藏自增主键仅表无主键 / 唯一索引时生效**和 MVCC **无关仅用于物理存储五、Undo Log 日志 数据版本链1. Undo Log 核心作用Undo Log 即回滚日志是 InnoDB 核心日志之一主要有两大作用事务回滚事务失败或执行 ROLLBACK 时依靠 undo log 恢复数据保证事务原子性支撑 MVCC存储数据历史版本为快照读提供旧数据实现无锁读取。2. 版本链定义同一条数据的所有历史版本通过 DB_ROLL_PTR 回滚指针串联形成的单向链表称之为版本链。版本链规则链表头节点数据最新版本磁盘物理数据链表后续节点undo log 中存储的历史旧版本每次修改数据都会生成新版本并挂载到链表头部。版本链生成示例事务 10 插入数据 id1,name张三 → 版本 1TRX_ID10事务 20 修改为 李四 → 版本 2TRX_ID20指针指向版本 1事务 30 修改为 王五 → 版本 3TRX_ID30指针指向版本 2。最终版本链版本 3最新 → 版本 2 → 版本 1最旧六、ReadView 读视图可见性判断核心ReadView 是快照读时生成的一致性视图核心作用**遍历版本链判断当前事务能看到哪个历史版本**是实现事务隔离级别的关键。1. ReadView 四大核心字段字段名详细作用m_ids生成 ReadView 瞬间数据库中所有活跃、未提交的事务 ID 集合min_trx_idm_ids 集合中最小的事务 IDmax_trx_id系统下一个待分配的事务 ID全局自增creator_trx_id当前事务自身 ID创建该 ReadView 的事务2. 数据可见性规则按顺序判断取出数据版本的 DB_TRX_ID依次执行以下规则1、若 TRX_ID creator_trx_id当前数据由自己修改可见2、若 TRX_ID min_trx_id修改事务早已提交可见3、若 TRX_ID max_trx_id属于未来未开启的事务不可见4、若 TRX_ID 在 m_ids 中事务活跃未提交不可见不在集合中则代表已提交可见。兜底逻辑当前版本不可见时顺着版本链向前遍历旧版本直到找到可见版本无匹配则返回空。七、MVCC 实现 RC、RR 隔离级别两大隔离级别底层实现核心区别ReadView 的生成时机不同。1. 读已提交RC生成规则每执行一次快照读都会重新生成全新的 ReadView效果每次查询都能感知数据库最新事务状态可以读到其他事务刚提交的数据特点解决脏读**会出现不可重复读**数据实时性强。2. 可重复读RRMySQL 默认级别生成规则事务中第一次执行快照读时生成 ReadView后续所有查询复用该视图效果整个事务周期内查询结果和首次查询保持一致特点解决脏读、不可重复读配合间隙锁可解决大部分幻读问题是 MySQL 默认隔离级别。八、全文核心总结面试必背MVCC 本质依靠行隐式字段 undo log 版本链 ReadView实现无锁多版本并发控制兼顾性能与隔离性两种读模式普通 SELECT 是快照读无锁、读历史版本增删改、加锁查询是当前读加锁、读最新数据三大隐式字段DB_TRX_ID修改事务 ID、DB_ROLL_PTR版本链指针、DB_ROW_ID隐藏主键与 MVCC 无关版本链由回滚指针串联 undo log 中的历史数据版本隔离级别核心RC 每次查询新建 ReadViewRR 仅首次查询创建 ReadView 并全程复用。
【MySQL】MVCC底层原理超全详解(快照读/当前读/版本链/ReadView/隔离级别)
发布时间:2026/5/31 3:13:14
大家好我是程序员二叉。一、简介MVCC多版本并发控制是 MySQL InnoDB 引擎的核心机制也是后端面试高频考点。它可以无锁实现读写并发解决读写互相阻塞的性能问题同时支撑了 MySQL 两大事务隔离级别读已提交RC、可重复读RR。本文全面拆解 MVCC 底层原理包含快照读与当前读、行隐式字段、undo log 与版本链、ReadView 视图、隔离级别实现等内容适合学习与面试背诵欢迎点赞收藏关注。二、MVCC 核心概述MVCC 全称Multi-Version Concurrency Control多版本并发控制仅针对 InnoDB 存储引擎生效。核心作用实现无锁读读写互不阻塞大幅提升数据库并发能力依靠数据多版本机制规避脏读、不可重复读实现不同事务隔离级别。MVCC 三大核心要素行隐式字段 undo log 版本链 ReadView 读视图。三、两种读取模式快照读 当前读InnoDB 的读操作分为两类是理解 MVCC 的基础二者核心区别读取历史快照数据 / 读取最新实时数据。1. 快照读Snapshot Read定义无锁读取读取事务快照中的历史版本数据读写互不阻塞并发性能高。触发语句普通无锁SELECT查询。-- 典型快照读SELECT*FROMuserWHEREid1;举例可重复读级别事务 A 开启事务首次查询 id1结果为 name张三事务 B 修改数据为 name李四并提交事务事务 A 再次执行相同查询依旧读到 name张三。原理事务 A 读取的是事务启动时的快照数据并非数据库最新数据。2. 当前读Current Read定义加锁读取强制读取数据库最新已提交数据属于悲观锁机制会产生锁阻塞。触发语句所有增删改操作、加锁查询均为当前读。-- 加锁查询当前读SELECT*FROMuserWHEREid1FORUPDATE;SELECT*FROMuserWHEREid1LOCKINSHAREMODE;-- 写入操作底层都是当前读UPDATEuserSETname李四WHEREid1;DELETEFROMuserWHEREid1;举例事务 A 执行 FOR UPDATE 加锁查询无论其他事务是否修改提交数据始终读取最新数据。四、InnoDB 行三大隐式字段InnoDB 会为每一行数据自动添加 3 个隐藏字段是 MVCC 实现的底层数据支撑。隐式字段名占用字节核心作用DB_TRX_ID6记录最后修改当前行的事务 ID增 / 改 / 删都会更新标记数据版本归属是可见性判断依据DB_ROLL_PTR7回滚指针指向 undo log 中上一个历史版本串联所有版本形成版本链DB_ROW_ID8隐藏自增主键仅表无主键 / 唯一索引时生效**和 MVCC **无关仅用于物理存储五、Undo Log 日志 数据版本链1. Undo Log 核心作用Undo Log 即回滚日志是 InnoDB 核心日志之一主要有两大作用事务回滚事务失败或执行 ROLLBACK 时依靠 undo log 恢复数据保证事务原子性支撑 MVCC存储数据历史版本为快照读提供旧数据实现无锁读取。2. 版本链定义同一条数据的所有历史版本通过 DB_ROLL_PTR 回滚指针串联形成的单向链表称之为版本链。版本链规则链表头节点数据最新版本磁盘物理数据链表后续节点undo log 中存储的历史旧版本每次修改数据都会生成新版本并挂载到链表头部。版本链生成示例事务 10 插入数据 id1,name张三 → 版本 1TRX_ID10事务 20 修改为 李四 → 版本 2TRX_ID20指针指向版本 1事务 30 修改为 王五 → 版本 3TRX_ID30指针指向版本 2。最终版本链版本 3最新 → 版本 2 → 版本 1最旧六、ReadView 读视图可见性判断核心ReadView 是快照读时生成的一致性视图核心作用**遍历版本链判断当前事务能看到哪个历史版本**是实现事务隔离级别的关键。1. ReadView 四大核心字段字段名详细作用m_ids生成 ReadView 瞬间数据库中所有活跃、未提交的事务 ID 集合min_trx_idm_ids 集合中最小的事务 IDmax_trx_id系统下一个待分配的事务 ID全局自增creator_trx_id当前事务自身 ID创建该 ReadView 的事务2. 数据可见性规则按顺序判断取出数据版本的 DB_TRX_ID依次执行以下规则1、若 TRX_ID creator_trx_id当前数据由自己修改可见2、若 TRX_ID min_trx_id修改事务早已提交可见3、若 TRX_ID max_trx_id属于未来未开启的事务不可见4、若 TRX_ID 在 m_ids 中事务活跃未提交不可见不在集合中则代表已提交可见。兜底逻辑当前版本不可见时顺着版本链向前遍历旧版本直到找到可见版本无匹配则返回空。七、MVCC 实现 RC、RR 隔离级别两大隔离级别底层实现核心区别ReadView 的生成时机不同。1. 读已提交RC生成规则每执行一次快照读都会重新生成全新的 ReadView效果每次查询都能感知数据库最新事务状态可以读到其他事务刚提交的数据特点解决脏读**会出现不可重复读**数据实时性强。2. 可重复读RRMySQL 默认级别生成规则事务中第一次执行快照读时生成 ReadView后续所有查询复用该视图效果整个事务周期内查询结果和首次查询保持一致特点解决脏读、不可重复读配合间隙锁可解决大部分幻读问题是 MySQL 默认隔离级别。八、全文核心总结面试必背MVCC 本质依靠行隐式字段 undo log 版本链 ReadView实现无锁多版本并发控制兼顾性能与隔离性两种读模式普通 SELECT 是快照读无锁、读历史版本增删改、加锁查询是当前读加锁、读最新数据三大隐式字段DB_TRX_ID修改事务 ID、DB_ROLL_PTR版本链指针、DB_ROW_ID隐藏主键与 MVCC 无关版本链由回滚指针串联 undo log 中的历史数据版本隔离级别核心RC 每次查询新建 ReadViewRR 仅首次查询创建 ReadView 并全程复用。