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

浅析MySQL InnoDB存储引擎的MVCC实现原理 - 指南

文章目录

  • 摘要
  • 1. MVCC的核心思想与价值
  • 2. InnoDB MVCC建立的四大基石
    • 2.1. 记录中的隐藏列:版本控制的元数据
    • 2.2. Undo Log:构建数据历史版本的档案馆
    • 2.3. 事务ID(Transaction ID):标识事务的唯一身份
    • 2.4. Read View(读视图):决定数据可见性的“快照”‍
  • 3. 后台清理:Purge线程与空间回收
  • 4. MVCC建立的版本演进:MySQL 5.7 vs. MySQL 8.0
  • 5. 结论

摘要

多版本并发控制(Multi-Version Concurrency Control, MVCC)是现代关系型数据库应对高并发场景下读写冲突、提升性能的核心机制。MySQL的InnoDB存储引擎经过一套精密的设计,搭建了高效的MVCC,从而在保证事务隔离性的前提下,极大限度地协助了“非锁定读”(Non-locking Read)。本文将系统性地、深入地剖析InnoDB MVCC的实现原理,涵盖其核心构成要素,包括行记录中的隐藏字段、Undo日志与版本链、Read View(读视图)以及后台的Purge线程,并结合不同MySQL版本的演进,探讨其架构的优化与差异。

1. MVCC的核心思想与价值

在数据库并发操作中,最简单的并发控制方式是加锁,即读操作加共享锁(S锁),写操作加排他锁(X锁)。这种方式哪怕能保证数据一致性,但“读写互斥”的特性在高并发场景下会导致严重的性能瓶颈。

MVCC的核心思想是“空间换时间”,它凭借保存数据的多个历史版本,使得读写操作可以并行不悖。具体来说,当一个事务需要读取数据时,数据库不是直接返回最新的数据,而是根据事务的“快照”时间点,为其提供一个在该时间点上“可见”的数据版本。这样,读操作就不需要等待写管理释放锁,写操作也不必等待读操作完成,从而显著提升了数据库的并发处理能力。InnoDB存储引擎正是通过MVCC机制,在 READ-COMMITTED 和 REPEATABLE-READ 这两种隔离级别下达成了非锁定的一致性读。

2. InnoDB MVCC实现的四大基石

一个由多个组件协同工作的复杂平台。其实现主要依赖于以下四个关键部分:就是InnoDB的MVCC实现并非单一技术,而

2.1. 记录中的隐藏列:版本控制的元数据

:就是InnoDB为每个表中的每一行记录都额外添加了几个隐藏的系统列。这些列对用户透明,但在MVCC机制中扮演着至关重要的角色 。最核心的三个隐藏列

2.2. Undo Log:构建资料历史版本的档案馆

MVCC构建的物质基础,它承载着两个核心功能:就是Undo Log(撤销日志)事务回滚版本控制

  • 双重职责:当事务需要回滚时,InnoDB可以利用Undo Log中记录的“前镜像”将数据恢复到修改之前的状态,从而保证事务的原子性。在MVCC中,Undo Log则被用来存储数据行的历史版本,供并发的读事务查询。
  • 版本链的形成:当一个事务执行UPDATE操作时,其流程如下:
    1. InnoDB最初将要被修改的行的原始数据(包括DB_TRX_ID和DB_ROLL_PTR等信息)复制一份,形成一条Undo Log记录。
    2. 这条新的Undo Log记录本身也包含一个指针,指向更早的Undo Log记录,从而将版本链延续下去。
    3. 修改数据页上当前行的数据,将新值写入。
    4. 更新当前行的DB_TRX_ID为当前事务的ID。
    5. 将当前行的DB_ROLL_PTR指向刚刚在Undo Log中创建的那条记录。

“最新”版本的数据,而所有历史版本都通过DB_ROLL_PTR指针串联在Undo Log中,形成一个从新到旧的单向链表。就是通过此种方式,数据页上存储的永远

  • Undo Log的类型与管理:Undo Log在逻辑上分为两种:insert undo log和update undo log。insert undo log仅在事务回滚时需要,一旦事务提交即可丢弃。而update undo log由于可能需要被其他事务用于一致性读,因此在事务提交后不能立即删除,必须等待不再有任何事务需要它为止。这些日志被组织在回滚段(Rollback Segment)中进行管理。

2.3. 事务ID(Transaction ID):标识事务的唯一身份

事务ID (TRX_ID) 是一个严格单调递增的唯一数字,用于标识每一个对数据进行修改的事务。

2.4. Read View(读视图):决定数据可见性的“快照”‍

如果说Undo Log提供了数据的多版本,那么Read View就是决定一个事务“能看到”哪个版本的核心机制 。它是一个数据结构,在事务执行“快照读”(如普通SELECT语句)时创建,本质上是定义了当前事务的可见性规则。

  • Read View的核心组件:一个Read View首要包含以下四个重要属性 :

    • trx_ids (或 m_ids):一个列表,记录了在创建此Read View时,系统中所有活跃(未提交)的事务ID。
    • up_limit_id:trx_ids列表中的最小事务ID。如果某行记录的DB_TRX_ID小于up_limit_id,说明修改该行的事务在Read View创建前就已提交,因此该版本对当前事务是可见的。
    • low_limit_id:创建Read View时,系统尚未分配的下一个事务ID。如果某行记录的DB_TRX_ID大于或等于low_limit_id,说明修改该行的事务在Read View创建后才开启,因此该版本对当前事务是不可见的。
    • creator_trx_id:创建该Read View的事务自身的ID。
  • 创建时机:Read View的创建时机直接决定了不同隔离级别的行为:

    • REPEATABLE READ (RR):在该隔离级别下,Read View仅在事务中的第一个快照读发生时创建一次,之后该事务内的所有SELECT查询都会复用该Read View。这就保证了在一个事务内多次读取同一行数据,总能看到相同的结果,实现了“可重复读”。
    • READ COMMITTED (RC):在该隔离级别下,每一次快照读(每个SELECT语句)执行时都会重新创建一个新的Read View。这意味着事务内的不同查询可能会看到其他已提交事务所做的修改,导致“不可重复读”。
  • 可见性判断算法否可见时,它会执行以下逻辑:就是:当一个事务使用其Read View去判断某一行记录的某个版本

    1. 获取待判断版本的DB_TRX_ID。
    2. 判断1:如果 DB_TRX_ID == creator_trx_id,表示这是由当前事务自己修改的版本,可见
    3. 判断2:如果 DB_TRX_ID < up_limit_id,表示修改该版本的事务在Read View创建前就已提交,可见
    4. 判断3:如果 DB_TRX_ID >= low_limit_id,表示修改该版本的事务在Read View创建后才开始,不可见
    5. 判断4:假如 up_limit_id <= DB_TRX_ID < low_limit_id,这表示修改该版本的事务在Read View创建时可能处于活跃状态。此时,需要在trx_ids列表中进行二分查找:
      • 如果 DB_TRX_ID存在于trx_ids 列表中,说明该事务在Read View创建时是活跃的,其所做的修改对当前事务不可见
      • 如果 DB_TRX_ID不存在于trx_ids 列表中,说明该事务在Read View创建时已经提交(即在up_limit_id之后开始,但在创建Read View之前就已提交),其所做的修改可见
    6. 遍历版本链:如果当前版本根据上述规则判断为不可见,事务就会沿着该版本的DB_ROLL_PTR回滚指针,去Undo Log中寻找上一个版本,然后对上一个版本重复执行以上的可见性判断流程,直到找到一个可见的版本为止。如果直到版本链末尾都找不到可见的版本,则意味着该行素材对当前事务来说“不存在”。

3. 后台清理:Purge线程与空间回收

随着平台的运行,Undo Log会不断增长。假设已提交事务的Undo Log不被清理,将导致存储空间的无限膨胀。Purge线程就是负责执行这项“垃圾回收”工作的后台线程。

4. MVCC实现的版本演进:MySQL 5.7 vs. MySQL 8.0

随着MySQL的发展,支持MVCC的底层架构也在不断优化,尤其在MySQL 8.0中有了显著的改进。

  • Undo表空间的组织方式

    • MySQL 5.7:默认情况下,Undo Log存储在共享的系统表空间(通常是ibdata1文档)中。纵然从5.6版本起就能够配置独立的Undo表空间,但这并非默认行为,且管理不便,容易导致ibdata1档案因Undo Log的增长而持续膨胀且无法收缩。
    • MySQL 8.0:做出了重大改变,默认创建两个独立的Undo表空间(undo_001 和 undo_002),并将Undo Log与系统表空间彻底分离 。此外,8.0还支持在线动态地增加、减少、启用、禁用Undo表空间,并能在线回收(Truncate)不再使用的Undo表空间,极大地提升了运维的灵活性和空间管理能力。
  • Purge线程的并行化

    • MySQL 5.7:Purge线程哪怕可以配置多个,但在某些场景下(如DML压力集中在少数表上),实际工作可能无法高效并行,导致单个Purge线程成为瓶颈,引发Purge lag(清理延迟)。
    • MySQL 8.0:通过innodb_purge_threads参数(默认值为4)提供了更强的并行清理能力。更关键的是,8.0改进了Purge线程的工作分配和协调机制。从8.0.26版本开始,系统能够自动监测Purge lag,如果延迟超过阈值,会自动将工作重新分配给其他空闲的Purge线程,管用避免了单线程瓶颈。

5. 结论

MySQL InnoDB存储引擎的MVCC实现是一个精巧而艰难的系统工程。它通过行记录隐藏列、Undo Log、事务ID和Read View这四大核心组件的协同工作,实现了在不加读锁的情况下,为并发事务提供一致性的素材视图,从而大幅提升了数据库的并发性能。

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

相关文章:

  • 如何快速构建AI智能助手:LangChain完整开发指南
  • 2025年智慧文旅产品供应商排名:口碑好的智慧文旅供应商推荐 - 工业品牌热点
  • mpv媒体播放器终极配置指南:从零开始打造完美播放体验
  • 2025年热门的大连校企合作的公司权威推荐榜 - 行业平台推荐
  • 基于VUE的玩具商城系统[VUE]-计算机毕业设计源码+LW文档
  • 力扣滑动窗口
  • OI 日记
  • ELMduino终极指南:快速构建OBD-II车辆监控系统
  • Fiddly完整指南:5个步骤将Readme.md转化为精美HTML页面
  • Next AI Draw.io:智能图表革命,用自然语言重塑可视化创作
  • 人格障碍诊断系统毕业论文+PPT(附源代码+演示视频)
  • 2025年评价高的烷基多糖苷厂家最新实力排行 - 品牌宣传支持者
  • Typora代码块功能优化与问题解决方案
  • Zookeeper集群支持动态添加机器?面试必看!(轻松搞定)
  • 裂缝检测数据集大全:助力计算机视觉研究
  • 科技巨头的生态构建之路:技术底座、技术生态与应用生态的协同演进
  • 2025年黑龙江艺考生文化课正规机构推荐:实力机构有哪些? - myqiye
  • PyGCL图对比学习框架:从入门到实战的完整指南
  • ag-ui终极指南:构建下一代AI代理应用的完整教程
  • AI_NovelGenerator:智能写作终极指南,一键生成万字小说
  • 偏置电压对于 MCP6S22 单边放大检波的影响
  • 2025年智慧旅游景区智慧化服务商推荐,精选智慧旅游品牌供应 - 工业品牌热点
  • 2025年度六安玻璃贴膜企业推荐:实力强的玻璃贴膜品牌企业有 - 工业推荐榜
  • 19、对等网络:颠覆性技术的潜力与挑战
  • ComfyUI与翻译系统集成:支持多语言提示词输入
  • 2025年知名的大连个人搬家公司企业公信力榜 - 行业平台推荐
  • Simple Form性能优化实战指南:Rails应用表单响应速度提升方案
  • BeepBox:开启你的免费在线音乐创作之旅
  • Croner终极指南:零依赖JavaScript定时任务的完整解决方案
  • 47、深入探索Bash脚本与Linux启动流程