当前位置: 首页 > news >正文

MySQL MVCC 核心原理:版本链、ReadView 与可见性判断

1. 什么是 MVCC?

MVCC 全称是Multi-Version Concurrency Control,即多版本并发控制。它的核心思想是:为同一行数据维护多个版本,让读写在很多情况下不用互相阻塞。

在没有 MVCC 时,读写冲突通常要大量依赖锁。MVCC 让普通SELECT可以读一个可见的数据版本,而不是必须等待正在修改这行数据的事务结束。

目标:普通SELECT读取合适版本,减少读写阻塞。

2. MVCC 依赖的三要素

InnoDB 的 MVCC 主要依赖以下三样东西:

  1. 记录中的隐藏字段
  2. undo log 版本链
  3. ReadView 读视图

这三者配合,解决一个核心问题:当前事务应该看到这行数据的哪个版本?

3. 记录中的隐藏字段

InnoDB 每行记录除了业务字段,还会维护一些隐藏字段:

隐藏字段含义
DB_TRX_ID最近一次修改这行记录的事务 ID
DB_ROLL_PTR回滚指针,指向 undo log 中的上一个版本
DB_ROW_ID隐藏行 ID,没有主键时可能使用

其中DB_TRX_IDDB_ROLL_PTR是理解 MVCC 的关键。

4. undo log 版本链

当一行数据被多个事务修改时,undo log 会形成一条版本链。链表头部通常靠近较新的旧版本,沿着roll_pointer可以找到更早的版本。

例如一条记录从 A1 被改成 A2,又被改成 A3。当前数据页里是最新值,而 undo log 中保存旧值。不同事务根据可见性规则,可能读到 A3、A2 或 A1。

5. 当前读与快照读

不是所有读都走 MVCC 快照。

类型SQL 示例特点
当前读SELECT ... FOR UPDATEUPDATEDELETEINSERT读取最新版本,并加锁
快照读普通SELECT读取可见版本,不加锁,非阻塞

MVCC 主要服务于快照读。普通SELECT不加锁也能在并发写入时稳定读取,就是因为它读的是某个可见版本。

6. ReadView 是什么?

ReadView 是快照读执行时生成的读视图,用来判断版本链上的某个版本是否对当前事务可见。

ReadView 中有四个核心字段:

字段含义
creator_trx_id创建这个 ReadView 的事务 ID
m_ids创建 ReadView 时活跃且未提交的事务 ID 集合
min_trx_id活跃事务中的最小 ID
max_trx_id下一个将要分配的事务 ID

7. 版本可见性规则

当沿着版本链找到某个版本时,会拿这个版本的trx_id和 ReadView 比较。

不可见就沿版本链找更旧的版本,直到找到可见记录。

这块最适合按流程走。每遇到一个版本,就问几个问题:

规则可以简化为:

  1. trx_id == creator_trx_id:自己改的,能看见。
  2. trx_id < min_trx_id:这个版本在 ReadView 生成前已经提交,能看见。
  3. trx_id >= max_trx_id:这个版本在 ReadView 生成后才出现,不能看见。
  4. min_trx_id <= trx_id < max_trx_id
    • 如果trx_id不在m_ids中,说明已提交,能看见;
    • 如果在m_ids中,说明当时还活跃,不能看见。

这些规则的目的很朴素:只让当前事务看到它应该看到的已提交版本

8. RC 和 RR 的区别

READ COMMITTED 和 REPEATABLE READ 的核心差异之一,是生成 ReadView 的时机不同。

隔离级别ReadView 生成时机结果
READ COMMITTED每次执行快照读都生成新的 ReadView同一事务内多次查询可能看到新提交数据
REPEATABLE READ第一次快照读生成 ReadView,后续复用同一事务内多次查询结果更稳定

两种隔离级别的差别,可以这样看:

这也解释了为什么 RC 下可能出现不可重复读,而 RR 能让普通快照读保持可重复。

9. 一个简单例子

假设事务 5 创建了 ReadView:

  • m_ids = {3, 4, 5}
  • min_trx_id = 3
  • max_trx_id = 6
  • creator_trx_id = 5

现在沿着版本链看到几个版本:

版本 trx_id是否可见原因
5可见当前事务自己修改
2可见小于 min_trx_id,早已提交
6不可见不小于 max_trx_id,属于更晚事务
4不可见在 m_ids 中,当时未提交

如果某个版本不可见,就继续沿着 undo log 版本链向前找,直到找到可见版本或没有更旧版本。

10. 面试回答模板

可以这样回答:

MVCC 是多版本并发控制,用来降低读写冲突。InnoDB 每行记录有隐藏字段,比如事务 ID 和回滚指针;更新数据时会生成 undo log,多个旧版本通过回滚指针形成版本链。普通 SELECT 是快照读,会基于 ReadView 判断版本是否可见。ReadView 中包含当前活跃事务集合、最小活跃事务 ID、下一个事务 ID 和创建者事务 ID。RC 隔离级别下每次快照读都会生成新的 ReadView,RR 隔离级别下第一次快照读生成后会复用,所以 RR 下多次读取更稳定。

11. 小结

MVCC 的难点不是名词多,而是要把它们串成一条线:隐藏字段记录版本信息,undo log 串起旧版本,ReadView 决定哪个版本可见。理解这条线,MVCC 就从“背概念”变成了“顺着链表找可见数据”。

http://www.zskr.cn/news/1426523.html

相关文章:

  • 综合算法 II | 分治与贪心
  • 如何解决空洞骑士Mod安装后游戏崩溃的完整指南
  • 2026最新遂宁市黄金回收铂金回收白银回收怎么选?多家靠谱门店实测对比及联系方式推荐 - 亦辰小黄鸭
  • LeetCode210.课程表II
  • 告别Android设备连接烦恼:UniversalAdbDriver终极解决方案
  • 2026最新吴忠市黄金回收铂金回收白银回收怎么选?多家靠谱门店实测对比及联系方式推荐 - 亦辰小黄鸭
  • 2026最新宁波市黄金回收铂金回收白银回收怎么选?多家靠谱门店实测对比及联系方式推荐 - 亦辰小黄鸭
  • 神经渲染新纪元:扩散模型原理、应用与未来展望
  • Go Web项目实战:接收上传的Excel文件,处理后再下载(附完整代码)
  • 2026最新太原市黄金回收铂金回收白银回收怎么选?多家靠谱门店实测对比及联系方式推荐 - 亦辰小黄鸭
  • Claude 4.7 Opus 新手极速上手指南
  • 无核边界积分法:Brinkman界面问题的配点法与单位分解求解
  • 2026最新攀枝花市黄金回收铂金回收白银回收怎么选?多家靠谱门店实测对比及联系方式推荐 - 亦辰小黄鸭
  • 安路Modelsim仿真库编译
  • 2026年揭阳市本地黄金回收白银回收铂金回收靠谱门店权威榜第一名:足金首饰+投资金条+银条+旧料黄金上门变现无套路收费+门店地址及联系方式推荐 - 前途无量YY
  • Node.js项目依赖下载太慢?试试这3种镜像源加速方案(npm/cnpm/yarn)
  • Hollow Knight Mod终极安装指南:使用Scarab解决版本兼容性问题
  • Seraphine:如何用3分钟让你的英雄联盟游戏体验提升一个段位?
  • 基于STM32实现LVGL移植、显示(LVGL版本8.3.10)
  • Spring Boot项目实战:用dynamic-datasource和Druid给你的数据库密码‘上锁’(附自定义密钥教程)
  • 瑞祥商联卡回收流程全攻略:快速、安全的操作指南 - 团团收购物卡回收
  • 别再只导整个模型了!教你像搭积木一样复用FBX里的网格和材质
  • 江西信息流广告服务商哪家好:前五排名深度测评 - 服务品牌热点
  • BurpSuite抓不到HTTPS?手把手教你搞定CA证书安装(Chrome/Firefox/Edge全平台)
  • Vue2 和 Vue3 区别?选项式 API vs 组合式 API
  • 终极Windows右键菜单优化指南:用ContextMenuManager让你的右键菜单秒开如飞
  • RAG增强召回的方法(三)垂直领域
  • 2026最新郴州市黄金回收铂金回收白银回收怎么选?多家靠谱门店实测对比及联系方式推荐 - 亦辰小黄鸭
  • 5分钟上手:Snap.Hutao原神工具箱让你的游戏体验翻倍提升
  • 第01章 Agent时代为什么还要CLI