InnoDB 存储引擎

news/2025/10/26 16:25:26/文章来源:https://www.cnblogs.com/gaoyxxx/p/19166975

1. 逻辑存储结构

InnoDB 的逻辑存储结构是其管理数据、支撑核心能力的底层骨架,它以 “表空间→段→区→页→行” 的五层架构,将数据从宏观存储容器到微观记录层层划分。这套结构不仅决定了数据在磁盘的存储与访问规则,更是理解 B+ 树索引、事务、MVCC 等 InnoDB 核心特性的关键前提 —— 本章将从宏观到微观拆解这套结构,帮你建立对 InnoDB 底层工作逻辑的整体认知。

表空间(Tablespace):顶层存储容器

  • 定义:InnoDB 逻辑存储的最高层次,是所有数据(系统数据、用户数据、索引等)的总仓库
  • 类型:
    • 系统表空间:默认ibdata1文件,存储数据字典、undo 日志等核心系统数据
    • 独立表空间:也就是每一张用户表,每个用户表都对应着一个.ibd文件(由innodb_file_per_table控制),独立存储表的数据和索引,便于单表管理。
  • 作用:通俗来讲,表空间就是用来隔离不同数据(系统数据 / 用户表),是我们整个逻辑存储结构中的最上层建筑。

段(Segment):功能化的数据组,与B+树直接关联

  • 定义:表空间下按功能划分的存储单元,是B+树索引的存储容器
  • 类型:
    • 数据段:对应表的聚簇索引B+树(InnoDB 中聚簇索引包含了数据行的全部信息,与数据物理存储绑定,数据段即为聚簇索引的存储载体)
    • 索引段:每个非聚簇索引对应一个独立的索引段,存储非聚簇索引B+树的所有节点。
    • 回滚段:存储undo日志,用于事务回滚和MVCC,与B+树无关。(在系统表空间中)
  • 作用:按功能隔离索引数据(聚簇索引 / 非聚簇索引),确保不同所用不相互干扰,通俗说,一个段就是一棵B+树

区(Extent):段的最小分配单位,平衡效率与碎片化

  • 定义:连接段与页的中间层,是段申请空间的最小单位,固定为1MB(默认页大小为16KB,包含64个连续页)
  • 作用:
    • 避免碎片化:如果直接由段申请页(B+树节点),那么会出现大量页在磁盘空间不连续的情况,所以在申请时,我们设计了一个聚合单元---区,来批量的申请连续的页,这些页在磁盘上物理连续,提升B+树查询的“连续IO效率(减少磁头移动)
    • 降低管理成本:批量分配区代替零散分配页,减少空间管理的映射关系,减少系统开销。
    • 适配段增长:一次分配1MB空间,满足段(B+树)一段时间的增长,减少频繁空间申请的性能损耗。

页(Page):最小 IO 单位,对应 B+ 树的节点

  • 定义:InnoDB 与磁盘交互的最小单位(默认16KB),是B+树节点的物理载体。
  • 与B+树关系::
    • 每个B+树节点(叶子+非叶子)都完整存储在一个页中,确保一次 I/O 可以加载 / 写入一个节点。
    • 非叶子节点(索引页):存储 “索引键 + 子节点指针”,用于索引导航。
    • 叶子节点(数据页 / 索引页):聚簇索引的叶子节点存储完整行记录;非聚簇索引叶子节点存储“索引键+主键”(用于回表)
  • 类型:数据页、索引页、undo 页、redo 页等

行(Row):最小数据单元,存储用户记录

  • 定义:对应表中的一条记录,是存储用户数据的最小逻辑单位。
  • 存储特性:
    • 行数据按“行格式”(默认的Dynamic)存储,含隐藏列:**DB_ROW_IDDB_TRX_IDDB_ROLL_PTR),支持MVCC和事务管理。
    • 若行数据过大(超过页空间-约15KB),会触发“行溢出”:大字段核心部分(20字节前缀,含溢出页指针)存于原始数据页,剩余部分存于“溢出页”
  • 与B+树关系:行是聚簇索引B+树叶子节点的组成单元,按逐渐有序存储在叶子节点(数据页)中。

关于隐藏列的补充:

InnoDB 行的三个隐藏列(DB_ROW_IDDB_TRX_IDDB_ROLL_PTR)是支撑其事务、MVCC(多版本并发控制)和行标识的 “底层基石”,它们不对外显示(用 SELECT * 查不到),但会自动为每行数据添加(部分列按需生成)。
1. DB_ROW_ID:行的 “默认唯一标识”(可选)

  • 作用:当表没有显式定义主键,且没有非空唯一索引时,InnoDB 会自动生成该列作为行的 “隐形主键”,确保每行有唯一标识。
  • 特性:
  • 类型为 6 字节无符号整数,按插入顺序自增;
  • 若表有主键或非空唯一索引,InnoDB 会用这些索引列作为行的唯一标识,不会生成 DB_ROW_ID(避免冗余)。
  • 核心用途:填补 “无主键表” 的唯一标识空缺,保证行的物理唯一性,支持 InnoDB 内部的行管理(如页内排序)。

2. DB_TRX_ID:行的 “事务版本标识”

  • 作用:记录最后一次修改该行的事务 ID(包括插入、更新、删除操作),是 MVCC 判断 “行版本可见性” 的核心依据。
  • 特性:
  • 类型为 6 字节整数,每个事务启动时会分配一个全局唯一的事务 ID;
  • 每次事务修改该行(如 UPDATE/DELETE),都会将当前事务 ID 写入 DB_TRX_ID,覆盖旧值。
  • 核心用途:MVCC 中,通过对比 “当前事务 ID” 与行的 DB_TRX_ID,判断该行数据对当前事务是否 “可见”(比如:若行的 DB_TRX_ID 大于当前事务 ID,说明是未来事务修改的,不可见)。

3. DB_ROLL_PTR:行的 “历史版本指针”

  • 作用:指向该行 “历史版本数据” 在 undo 日志中的位置,是事务回滚和 MVCC 读取 “旧版本数据” 的关键。
  • 特性:
  • 类型为 7 字节指针,本质是 undo 日志页的地址 + 页内偏移;
  • 每次修改行时,InnoDB 会先将该行的 “修改前数据” 存入 undo 日志,再用 DB_ROLL_PTR 指向这个 undo 日志条目;
  • 多次修改后,DB_ROLL_PTR 会形成 “版本链”(最新行指向最近一次的旧版本,旧版本再指向更早的版本)。
  • 核心用途:
  • 事务回滚时:通过 DB_ROLL_PTR 找到 undo 日志中的旧数据,将行恢复到修改前状态;
  • MVCC 读时:若当前行版本不可见,通过 DB_ROLL_PTR 追溯历史版本,直到找到可见的旧版本。

三者协同作用:支撑 InnoDB 事务与并发
三个隐藏列并非孤立,而是共同服务于 InnoDB 的核心能力:

  • 无主键时,DB_ROW_ID 保证行唯一;
  • 事务修改行时,DB_TRX_ID 标记版本,DB_ROLL_PTR 记录历史;
  • MVCC 读时,通过 DB_TRX_ID 判可见性,通过 DB_ROLL_PTR 找旧版本;
  • 事务回滚时,通过 DB_ROLL_PTR 恢复数据。
    简单说:它们是 InnoDB 实现 “事务安全” 和 “高并发读写” 的 “隐形基础设施”。

2. 架构

MySQL5.5 开始就选择 InnoDB 作为默认存储引擎,他擅长处理事务,具有崩溃恢复的特性,在日常开发中使用广泛。下面为InnoDB架构图,左侧为内存结构,右侧为磁盘结构。

1761455429075.png

内存结构

上图中可以看到MySQL内存结构主要有四个部分:Buffer Pool(缓冲池)、Change Buffer(变更缓冲)、Adaptive Hash Index(自适应哈希索引)、Log Buffer(日志缓冲区)。其中Buffer Pool是内存结构的核心,通常占物理内存的 50%-70%,所有组件共同作用以减少磁盘 IO,加速数据访问。

  1. Buffer Pool:核心数据缓存区

    作用为:缓存磁盘上的热点数据页(数据页、索引页、undo页等),让后续操作在内存中完成,避免频繁访问磁盘

    (1)缓存的内容

    缓冲池的缓存单位为“页”(与磁盘页大小一致,默认16KB),主要包括:

    • 数据页:聚簇索引叶子节点的页(存储完整业务行数据)
    • 索引页:非叶子节点的索引页(键+指针)、非聚簇索引的叶子节点页(索引键+主键)
    • undo页:缓存undo日志页,加速事务回滚和MVCC版本读取

    (2)内部管理

    1. LRU 链表(最少使用链表):只发生过读的页
    2. Free 链表(空闲页链表):未使用过的页
    3. Flush 链表(脏页链表):发生过修改的页,后台线程定时将脏页批量刷盘,减少磁盘 IO
  2. Change Buffer:优化非聚集索引的写操作

    非聚簇索引的修改较为随机,不像主键索引:直接顺序写入磁盘,所以为了提高性能,当发生DML时(数据不在 Buffer Pool),会先将修改的操作记录在 Change Buffer 中,将修改缓存下来,等到被修改的数据进入到 Buffer Pool 时,再做合并,合并出修改后的数据再一起写回磁盘。

  3. Adaptive Hash Index:自适应 hash 索引

    用于优化对 Buffer Pool 数据的查询。InnoDB 存储引擎会监控对表中各索引页的查询,如果观察到 hash 索引可以提速,则建立哈希索引。

    这玩意一般不需要人工干预,是系统根据情况自动完成的。参数:adaptive_hash_index

  4. Log Buffer:日志缓冲区

    用来保存要写入磁盘中的log日志数据(redo log、undo log),默认大小为 16MB,日志缓冲区的日志会定期刷新到磁盘中。如果需要更新、插入或删除多行的事务,可以增加日志缓冲区的大小来节省磁盘 IO

    参数:

    innodb_log_buffer_size:缓冲区大小

    innodb_flush_log_at_trx_commit:日志刷新到磁盘时机

    Log Buffer 的刷盘时机由参数 innodb_flush_log_at_trx_commit 控制,常见配置:
    0:事务提交时不刷盘,仅依赖后台线程每 1 秒刷盘(性能最高,但崩溃可能丢失 1 秒内的日志);
    1(默认):事务提交时强制刷盘(最安全,崩溃无数据丢失,但性能略低);
    2:事务提交时仅刷到操作系统缓存,操作系统定期刷盘(平衡安全与性能,崩溃可能丢失操作系统缓存中的日志)。
    

磁盘架构

InnoDB 的磁盘结构是数据持久化存储的载体,与内存结构(如缓冲池、日志缓冲区)对应,主要由 表空间文件、redo 日志文件、undo 日志文件 三大核心模块构成,此外还有表结构定义文件等辅助文件。这些文件共同实现数据的持久化、事务恢复和逻辑存储管理,是 InnoDB 数据不丢失的基础。

  1. 表空间文件:核心数据存储在题

    表空间文件是 InnoDB 磁盘结构的核心,直接对应逻辑存储结构中的表空间,用于存储所有业务数据、索引、回滚段等核心信息。

    (1)系统表空间

    • 文件表示:默认生成ibdata1文件,可配置多个文件或自动扩展
    • 存储内容:
      • InnoDB 数据字典(记录数据库、表、索引的元数据,如“表user的字段类型、索引结构”)
      • 回滚段:MySQL5.x 及 8.0 未配置独立 undo 表空间时,回滚段和 undo 日志存于此
      • 临时表空间的溢出数据

    (2)独立表空间

    • 文件标识:每个用户表对应一个独立文件,命名未表名.ibd,由参数innodb_file_per_table=ON控制
    • 存储内容:
      • 对应表中“数据段”
      • 对应表中索引段
      • 表的 undo 日志

    (3)undo 表空间

    • 文件标识:MySQL8.0 默认生成undo_001undo_002两个文件(可配置数量)
    • 存储内容:
      • 所有事物的undo日志(用于回滚和MVCC版本读取)
      • 回滚段(MySQL8.0 后,回滚段从系统表空间迁移至undo表空间)

    (4)临时表空间

    • 文件标识:会话临时表:#innodb_tmp目录下的临时文件和全局临时表空间ibtmp1文件
    • 存储内容:
      • 会话临时表:CREATE TEMPORARY TABLE创建的表的数据和索引
      • 排序、分组等操作产生的临时结果集
  2. 重做日志文件(redo log):事务 “不丢数据” 的保障

    redo log 是 InnoDB 实现 “崩溃恢复” 和 “事务持久性” 的核心,没它数据可能丢:

    • 文件:默认 2 个ib_logfile0/ib_logfile1(循环写入,避免单点故障)。
    • 作用:记录 “数据物理修改的日志”(比如 “修改 user 表 id=100 的 age 为 25”),数据库崩溃后重启,通过它恢复 “已提交但没写到表空间的数据”。
    • 关键:顺序写磁盘(比表空间的随机写快 10 倍以上),按固定大小循环覆盖(需先确保日志对应的数据已刷到表空间)。
  3. 辅助文件:配合核心文件工作

    这类文件不存核心业务数据,但运维和故障排查离不开:

    • (1)表结构文件:xxx.frm(MySQL 5.x)/ 内置到.ibd(8.0)
      • 5.x 版本:每个表 1 个表名.frm,存表结构(字段名、类型、约束);8.0 后合并到*.ibd里,不再单独生成。
    • (2)错误日志:error.log
      • 存 InnoDB 启动 / 崩溃 / 恢复的错误信息(比如 “redo log 损坏导致启动失败”),排障必看。

3. 事务原理

Redo Log

Redo Log 记录的是事务提交时数据页的物理修改,是用来实现事务的持久性

该日志文件由两部分组成:重做日志缓冲(redo log buffer)以及重做日志文件(redo log file),前者在内存中,后者在磁盘中。

当事务提交之后会把所有修改信息都存到该日志文件中,用于在刷新脏页到磁盘发生错误时,进行数据恢复使用。

注意:

  1. redo log 采用了Write-ahead logging(WAL),这个操作在事务提交前先将数据写入 redo log buffer,然后将 redo log 刷盘写入磁盘,这时再告诉 Server 层保存好了,可以提交事务了,然后再进行脏页写回磁盘,如果发生了崩溃,可以利用redo log 恢复
    • 事务提交前发生崩溃的话,没啥事,就是事务执行失败了,数据也不会发生更改,redo log 丢了也没事。
  2. redo log 在磁盘中是顺序的、循环的文件,redo log 的写入速度 > 脏页写回磁盘的速度,使用才使用 redo log

Undo Log

回滚日志,用于记录数据被修改前的信息,作用有俩:提供回滚和 MVCC

它保证了事务的 ACID 特性中的原子性(Atomicity)。

在事务没提交之前,MySQL 会先记录更新前的数据到 undo log 日志文件里面,当事务回滚时,可以利用 undo log 来进行回滚。如下图:

img

4. MVCC

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/946838.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

20232320 2025-2026-1 《网络与系统攻防技术》实验三实验报告

1.实验内容 主要是各种工具和命令的使用 (1)MSFVenom编码器使用,生成EXE、JAR、PHP、Python等多种格式文件 使用-e参数选择编码器,如x86/shikata_ga_nai 使用-i参数设置编码次数 使用-f参数指定输出格式 (2)Veil…

2025年中央空调主机保养/维修/清洗/维保/维护公司推荐排行榜,水处理维保,物业公司/医院/写字楼/商场中央空调主机维保公司精选

2025年中央空调主机保养/维修/清洗/维保/维护公司推荐排行榜,水处理维保,物业公司/医院/写字楼/商场中央空调主机维保公司精选 行业背景与发展趋势 中央空调系统作为现代建筑的重要组成部分,其运行效率与稳定性直接…

251025 模拟测 总结

挂得很惨,分数就不说了。 Pro.A这种题目都做不出来,我可以退役了,哇哦!其实很简单的,想复杂了。 弄一个递归,考虑每种情况——由于这个所谓 \(c\) - 好串是有一侧全是 \(c\) 还有一侧是 \(c+1\) - 好串,可以把左…

参考文献

Charles M, Ochieng S B. Strategic outsourcing and firm performance: a review of literature[J]. International Journal of Social Science and Humanities Research (IJSSHR) ISSN, 2023, 1(1): 20-29. Kocot D,…

[java 锁 02 - synchronized vs ReentrantLock ]

ReentrantLock 是 JDK 提供的手动锁(位于 java.util.concurrent.locks 包),与 synchronized 同为可重入锁,但用法和特性有显著区别。下面从 用法、核心区别、适用场景 三个维度对比,讲清楚它们的“讲究”: synch…

AI Agent 与 Agentic AI 系统:真正的区别是什么?

大多数人把这两个词混用——但一个负责执行任务,另一个旨在达成目标。教你如何区分(以及各自的适用场景)。先来澄清当下 AI 讨论中最常见的一处混淆。 你可能经常看到大家把“AI agent”和“agentic AI system”当成…

2025 年 10 月门窗十大品牌榜单揭晓,聚焦专业制造与品牌口碑的品质之选

2025 年 10 月门窗十大品牌榜单正式揭晓,该榜单由中国建筑金属结构协会、全国工商联家具装饰业商会联合发布,是行业内兼具权威性与公信力的综合实力评选结果。本次评选突破传统单一性能评估框架,以《铝合金门窗》(…

[LangChain] 09.LCEL

LangChain Expression Language,是 LangChain 提供的一种声明式构建 链式 调用流程的方式。它允许开发者用 .pipe() 操作符将不同的模块(如提示模板、模型、解析器等)连接起来,形成一个完整的“链(Chain)”。 LC…

2025年饮料包装设备厂家权威推荐榜:缠膜机/吹瓶机/膜包机/杀菌机/水处理/套标机/贴标机/洗瓶机/卸垛机/旋盖机/液氮机/装箱机/灌装生产线/一条龙生产线/配件/灌装机

2025年饮料包装设备厂家权威推荐榜:缠膜机/吹瓶机/膜包机/杀菌机/水处理/套标机/贴标机/洗瓶机/卸垛机/旋盖机/液氮机/装箱机/灌装生产线/一条龙生产线/配件/灌装机 行业背景与发展趋势 饮料包装设备行业作为食品工业…

算法与数据结构 9 - 重链剖分

引言 尽管有些题会卡重链剖分,但它仍是一种强大的树上问题处理工具。 在许多资料中,『树链剖分』默认指重链剖分,因为它用得最多。本文明确区分『重链剖分』和『树链剖分』。 重链剖分 定义 本文中『树』默认为有根…

2025 年 10 月 AI 写标书系统最新推荐,技术实力与市场口碑深度解析

招投标领域数字化转型加速推动 AI 写标书系统成为企业核心竞争力工具,为破解选型难题,招标投标协会联合 AI 办公技术创新联盟于 2025 年第三季度启动权威测评。本次测评覆盖 42 家主流品牌,横跨政府采购、工程建设等…

AI浏览器comet拉新,一单20美元(附详细教程)

AI浏览器comet拉新,一单20美元(附详细教程)1. Comet浏览器 Perplexity出的AI浏览器Comet,最近在和OpenAI打仗,这种大厂博弈期间,普通用户是最大收益者,最近搞了一波付费拉新活动: 我们先邀请用户注册Comet,并…

大样例通过后无法AC的可能

1.检查边界情况 2.测试程序运行时间 3.计算空间是否符合 4.检查数组大小 5.检查数组访问是否越界 6.检查STL是否越界(如果使用)

若依前后端分离版学习笔记(十八)——页面权限,页签缓存以及图标,字典,参数的利用

若依前后端分离版学习笔记(十八)——页面权限,页签缓存以及图标,字典,参数的利用2025-10-26 15:43 tlnshuju 阅读(0) 评论(0) 收藏 举报pre { white-space: pre !important; word-wrap: normal !important; o…

Spring Cloud Gateway网关路由配置 - AlanLee

Spring Cloud Gateway 配置使用 lb:// 协议时,需依赖以下组件:核心依赖 ‌Spring Cloud Gateway 依赖‌ 需添加 spring-cloud-starter-gateway 依赖,用于启用网关功能。 ‌<dependency><groupId>org.sp…

重构学习认知:从听讲、践行到教学的启示

读完 Scalers 关于大学生上课听讲的论述,以及娄老师围绕 “做中学” 与教练式教学的文章,不难发现这些内容共同指向了一套更科学的学习逻辑,打破了传统认知中对 “学习” 的单一理解,让人对如何高效获取知识、内化…

【c++】红黑树的部分构建

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

域登录态分享(类sso)

遇到一个问题,在同一主域下的多个子域之间共享登录状态的需求。例如:main.example.com 主站 learn.example.com 学习中心希望在任意子域登录后,其他子域也能自动识别登录状态,包括登出同步。Cookie 跨子域共享 浏览…

ssh原理

ssh原理 密码认证原理服务器生成一对公私钥,认证流程客户端发送请求给服务器服务器生成了一对公私钥,发送公钥给客户端客户端使用这个公钥进行加密,发送给服务端服务端通过私钥进行解密,认证成功后,就能连接上去了…

实现一个简易版本的IOC

简单的IOC其实就是一个map,key是对象名字,value是对象的实例,Spring容器初始化的时候会将配置文件或注解信息转换成BeanDefinition对象存储在集合中,然后遍历集合通过反射实例化Bean,实例化后的Bean会放入到名为si…