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

MySQL数据库中MVCC的底层原理

MVCC(多版本并发控制)是 MySQL 的 InnoDB 存储引擎实现高并发读写的核心技术。它的核心目标是实现**“读不加锁,读写互不阻塞”**,让读操作永远不阻塞写操作,写操作也永远不阻塞读操作,从而极大提升数据库的并发性能。

我们可以把 MVCC 比作“图书馆借书”:

  • 传统加锁机制:你要借书(读)时,管理员必须等你还书,才能修改这本书的内容(写),两者互相阻塞。
  • MVCC 机制:你要借书时,管理员直接复印一份当时的“副本”给你。与此同时,管理员可以随意修改原书。你手里的副本不会受原书修改的影响。

🛠️ MVCC 的底层三大核心组件

MVCC 的实现依赖于 InnoDB 的三大底层设计,它们共同协作完成了多版本数据的管理:

  1. 行记录的隐藏字段InnoDB 的每一行数据,除了我们自己定义的字段(如id,name),还会自动添加 3 个隐藏字段:

    • DB_TRX_ID(事务ID):记录最后一次插入或更新该行数据的事务 ID。
    • DB_ROLL_PTR(回滚指针):指向该行数据在 Undo Log 中的上一个历史版本。
    • DB_ROW_ID(行ID):如果没有设置主键,InnoDB 自动生成的隐藏主键(非 MVCC 核心,仅作了解)。
  2. Undo Log(回滚日志)与版本链当对某行数据进行 UPDATE 或 DELETE 操作时,InnoDB不会直接覆盖原数据,而是:

    • 把旧版本的数据写入 Undo Log。
    • 更新当前行的DB_TRX_ID为当前事务 ID。
    • 更新当前行的DB_ROLL_PTR指向 Undo Log 中的旧版本。

    经过多次修改后,这些历史版本通过DB_ROLL_PTR串联起来,就形成了一条单向的“版本链”。

  3. Read View(读视图)Read View 是事务在进行“快照读”(普通 SELECT)时生成的一个“可见性判断规则”。它主要包含 4 个核心信息:

    • m_ids:生成 Read View 时,当前系统中所有活跃(未提交)的事务 ID 列表。
    • min_trx_id:活跃事务中最小的事务 ID。
    • max_trx_id:系统分配给下一个事务的 ID(当前最大事务 ID + 1)。
    • creator_trx_id:当前事务自己的 ID。

🔍 版本可见性判断规则

当一个事务去读取某行数据时,它会拿着自己的 Read View,从版本链的最新版本开始,按照以下规则逐条判断该版本是否“可见”:

  1. 如果版本的DB_TRX_ID==creator_trx_id:说明是当前事务自己修改的数据,可见
  2. 如果版本的DB_TRX_ID<min_trx_id:说明修改该行的事务在生成 Read View 之前就已经提交了,可见
  3. 如果版本的DB_TRX_ID>=max_trx_id:说明修改该行的事务在当前事务之后才启动,不可见
  4. 如果版本的DB_TRX_IDmin_trx_idmax_trx_id之间:
    • 如果DB_TRX_IDm_ids列表中:说明该事务还未提交,不可见
    • 如果DB_TRX_ID不在m_ids列表中:说明该事务已经提交,可见

如果当前版本不可见,就顺着DB_ROLL_PTR找上一个历史版本继续判断,直到找到可见版本或遍历完整个版本链。


💡 实战例子:RC 与 RR 隔离级别的区别

MVCC 在不同隔离级别下的表现,核心区别在于Read View 的生成时机

场景设定:有一张users表,初始数据id=1, name="Alice"

例子 1:读已提交(RC)级别

规则:每次执行 SELECT 语句时,都会生成一个新的 Read View。

时间事务 A事务 BMVCC 行为解析
t0START TRANSACTION;
t1SELECT name FROM users WHERE id=1;生成 Read View 1,读到"Alice"
t2START TRANSACTION; UPDATE users SET name="Bob" WHERE id=1; COMMIT;B 修改并提交,生成新版本 "Bob",旧版本 "Alice" 存入 Undo Log。
t3SELECT name FROM users WHERE id=1;生成新的 Read View 2,根据规则能看到 B 提交的 "Bob",读到"Bob"

结果:事务 A 在同一个事务内,两次读到了不同的数据,这就是**“不可重复读”**。

例子 2:可重复读(RR)级别(MySQL 默认)

规则:在事务第一次执行 SELECT 时生成 Read View,整个事务期间复用这个 Read View。

时间事务 A事务 BMVCC 行为解析
t0START TRANSACTION;
t1SELECT name FROM users WHERE id=1;生成 Read View 1,读到"Alice"
t2START TRANSACTION; UPDATE users SET name="Bob" WHERE id=1; COMMIT;B 修改并提交,生成新版本 "Bob"。
t3SELECT name FROM users WHERE id=1;复用 Read View 1。根据 Read View 1 的规则,B 的事务 ID 属于“未提交活跃列表”,因此 "Bob" 版本不可见,顺着版本链读到旧版"Alice"

结果:事务 A 两次读到的都是 "Alice",保证了**“可重复读”**。


📌 补充说明:快照读与当前读

MVCC 仅对快照读(Snapshot Read)生效,也就是普通的SELECT语句。

对于当前读(Current Read),例如SELECT ... FOR UPDATEINSERTUPDATEDELETE,数据库会跳过 MVCC,直接读取数据的最新版本,并且必须加锁(排他锁或共享锁)来保证数据修改的原子性和一致性。

http://www.jsqmd.com/news/807171/

相关文章:

  • Claude代码工具包:AI编程工作流自动化与工程化实践
  • 差分隐私离场提示调优:本地生成安全提示,云端调用大模型
  • FPGA在物联网边缘计算中的核心价值与架构实践
  • 2026年牵手红娘服务权威推荐深度分析:婚恋平台线下见面率低与用户信任缺失痛点 - 品牌推荐
  • ARM架构错误记录状态寄存器(ERRSTATUS)解析与应用
  • Django Flask FastAPI 三者对比
  • 私域直播系统源码开发推荐:大健康行业如何搭建直播电商平台?
  • EMC设计实战:从电流路径管控到辐射发射排查的工程师指南
  • 从‘幂的末尾’到快速幂:一个OpenJudge例题带你入门算法优化(含同余定理详解)
  • 2026年牵手红娘服务权威推荐深度解析:婚恋市场线下见面率低与虚假信息泛滥痛点 - 品牌推荐
  • 精密度0.001mm的非标零件加工真的可行吗?
  • ARM MPMC动态内存控制器原理与应用实践
  • Java基础全套教程(三)—— 控制语句、方法、递归算法
  • 机箱机柜生产风险如何控制
  • Vibecoding 工具如何一次性生成 Web + iOS + Android 三端 APP?功能架构深度解读
  • 告别答辩PPT噩梦:百考通AI如何帮你高效搞定毕业答辩
  • 射频能量技术:从磁控管到智能固态系统的测量与工程实践
  • 2026年5月商业医保公司推荐:五家产品专业评测夜班族防高额自费压力 - 品牌推荐
  • 基于Helm Chart在Kubernetes中部署docker-mailserver邮件服务器
  • 三步搞定黑苹果配置:OpenCore Configurator完全指南
  • 硬件工程师必读:快节奏项目下的电路保护设计实战指南
  • SoC硬件辅助验证技术解析与应用实践
  • 基于GitHub Actions与静态站点构建个人数字足迹聚合系统
  • 黑莓转型复盘:从硬件崩塌到软件重生的战略启示
  • MySQL | DBeaver Mac版下载、安装与使用指南
  • 锂电池热失控防护:从封装技术到系统级安全设计
  • DLP Pico技术与近眼显示系统设计解析
  • 从电视伴音收音机消亡看数字技术演进与仪器集成化趋势
  • 【行情复盘】2026年5月12日(周二)
  • 芯片可测试性设计(DFT)原理与实践:从扫描链到低功耗测试