【数据库篇】MySQL InnoDB ibd 文件格式解析

article/2025/10/8 5:46:40

mysql innodb的表由.frm .ibd 组成,frm:存了每个表的元数据,包括表结构的定义等;ibd:存了每个表的元数据,包括表结构的定义等;

1.0 ibd文件基本结构

ibd文件由Tablespaces,Segments,Extents,Pages组成。
Tablespaces(FIL_PAGE_TYPE_FSP_HDR):是数据文件的第一个Page,存储表空间关键元数据信息。
Segments(FIL_PAGE_INODE):数据文件的第3个page,用于管理数据文件中的segement,每个索引占用2个segment,分别用于管理叶子节点和非叶子节点。
Extents(FIL_PAGE_TYPE_XDES):XDES Page除了文件头部外,其他都和FSP_HDR页具有相同的数据结构,可以称之为Extent描述页,每个Extent占用40个字节,一个XDES Page最多描述256个Extent。
Pages(FIL_PAGE_INDEX):是InnoDB管理存储空间的基本单位,一个页的大小一般是16KB。
在这里插入图片描述
新建一个数据库时,innodb存储引擎会初始化一个名为ibdata1 的表空间文件,这个文件会存储所有表的数据,以及我们所熟知但看不到的系统表sys_tables、sys_columns、sys_indexes 、sys_fields等。此外,还会存储用来保证数据完整性的回滚段数据;通过设置参数innodb_file_per_table,可以每一个表都对应一个自己的独立表空间文件,而不是存储到公共的ibdata1文件中。独立的表空间文件之存储对应表的B+树数据、索引和插入缓冲等信息,其余信息还是存储在默认表空间中。

1.1 PAGE类型是FIL_PAGE_TYPE_FSP_HDR的文件结构

是ibd的第一个page,记录整个表的Page管理信息,主要包含2种数据结构,分别为fsp header和xdes entry。
1.fsp header固定为112字节(是这个page的核心职责)
2.fsp header之后为xdes entry数组(256),每个entry管理64个page,1个page16K(即管理256M空间),该数组在FIL_PAGE_TYPE_XDES中介绍

1.1.1 基本结构介绍

在这里插入图片描述

1.1.2 表头介绍

在这里插入图片描述

  • space id 当前表空间的ID
  • size 当前space最大可容纳的page数,文件扩大时才会改变这个值
  • limit 当前space已经分配初始化的page数,包括空闲的和已经使用的
  • flag 未起作用
  • frage used FSP_FREE_FRAG列表中已经被使用的page数
  • free list space中可用的extent对象列表,extent里面没有一个page被使用
  • frag free list 有可用碎叶page的extent列表,exntent里面有部分page被使用
  • frag full list 没有有可用page的extent列表,exntent里面全部page被使用
  • segment id 下一个可利用的segment id
  • full inode list space当前完全占满的segment inode页列表
  • free inode list space当前完全占满的segment inode页列表,full inode list 和 free inode list的结构如下
    在这里插入图片描述

1.2 PAGE类型是FIL_PAGE_INODE的文件结构

段是表空间文件中的主要组织结构,它是一个逻辑概念,用来管理物理文件,是构成索引、表、回滚段的基本元素。创建一个索引(B+树)时会同时创建两个段,分别是内节点段和叶子段,内节点段用来管理(存储)B+树非叶子(页面)的数据,叶子段用来管理(存储)B+树叶子节点的数据;也就是说,在索引数据量一直增长的过程中,所有新的存储空间的申请,都是从“段”这个概念中申请的。
在这里插入图片描述
每个INODE ENTRY管理一个段(如索引段(即B+树的内部节点)下的所有extend(簇),数据段(B+树的叶子节点),回滚段等等),这个段下的所有页由extend(簇)来管理
在这里插入图片描述
inode entry字段解释
在这里插入图片描述

1.3 PAGE类型是FIL_PAGE_TYPE_XDES的文件结构

数据文件的第一个Page类型为FIL_PAGE_TYPE_FSP_HDR,在创建一个新的表空间时进行初始化(fsp_header_init),该page同时用于跟踪随后的256个Extent(约256MB文件大小)的空间管理,所以每隔256MB就要创建一个类似的数据页,类型为FIL_PAGE_TYPE_XDES ,XDES Page除了文件头部外,其他都和FSP_HDR页具有相同的数据结构,可以称之为Extent描述页,每个Extent占用40个字节,一个XDES Page最多描述256个Extent。
在这里插入图片描述

  • file segment id:段id,如果extent属于某个段的话,记录其段id,占用8个字节
  • xdes list node:extent链表的双向指针节点,占用12个字节,fsp header中的链表头指向的目标就是这里
  • state:该extent的状态,比如空闲或者已完全被使用等等,该状态是枚举类型,值为XDES_FREE,XDES_FREE_FRAG,XDES_FULL_FRAG,XDES_FSEG,占用4字节
  • page state bitmap: 用2个bit表示extent中的一个page,其中一个bit表示该page是否是空闲(XDES_FREE_BIT),另一个bit保留,尚未使用(XDES_CLEAN_BIT),占用16字节,16*8/2=64,正好可以标记一个extent 64个页的使用情况

1.4 PAGE类型是FIL_PAGE_INDEX的文件结构

是ibd的用于管理页节点和叶子节点的page。
在这里插入图片描述
User Records记录具体的数据内容,其中就包括数据库每行数据的具体数据,单条记录文件结构如下
在这里插入图片描述

如果是聚簇索引

索引结构:[主键列][TRXID][ROLLPTR][其他建表的非主键列]
参与记录比较的列:主键列
内节点key列:[主键列]+page No指针

如果是二级索引

索引结构:[索引列][主键列]
参与记录比较的列:[索引列][主键列]
内节点key列:[索引列][主键列]+page No指针

2.0 通过py_innodb_page_info查看ibd的基本信息,如下:

没有找到趁手的二进制分析工具分析idb文件,如果谁找到好的工具还望告知哈!我现在用的是Analysis这个工具

page offset 00000000, page type <File Space Header>   //page类型FIL_PAGE_TYPE_FSP_HDR
page offset 00000001, page type <Insert Buffer Bitmap>
page offset 00000002, page type <File Segment inode>   //page类型FIL_PAGE_INODE
page offset 00000003, page type <B-tree Node>, page level <0002>   //page类型FIL_PAGE_INDEX,Page Header->PAGE_LEVEL=2,是叶节点
page offset 00000004, page type <B-tree Node>, page level <0002>
page offset 00000005, page type <B-tree Node>, page level <0002>
page offset 00000006, page type <B-tree Node>, page level <0001>   //page类型FIL_PAGE_INDEX,Page Header->PAGE_LEVEL=1,是叶节点
page offset 00000007, page type <B-tree Node>, page level <0001>
page offset 00000008, page type <B-tree Node>, page level <0002>
page offset 00000009, page type <B-tree Node>, page level <0002>
page offset 0000000a, page type <B-tree Node>, page level <0000>   //page类型FIL_PAGE_INDEX,Page Header->PAGE_LEVEL=0,是叶子节点
page offset 0000000b, page type <B-tree Node>, page level <0000>
page offset 0000000c, page type <B-tree Node>, page level <0000>
page offset 0000000d, page type <B-tree Node>, page level <0000>
page offset 0000000e, page type <B-tree Node>, page level <0000>
page offset 0000000f, page type <B-tree Node>, page level <0000>
...
page offset 00000000, page type <Freshly Allocated Page>
page offset 00000000, page type <Freshly Allocated Page>
page offset 00000000, page type <Freshly Allocated Page>
page offset 00000000, page type <Freshly Allocated Page>
Total number of page: 14592:
Freshly Allocated Page: 2584
Insert Buffer Bitmap: 1
File Space Header: 1
B-tree Node: 12005
File Segment inode: 1

3.0 分析文件结构,对我们优化数据库的帮助

1.我们知道mysql的其中一个重要的性能瓶颈就是磁盘IO。如果一张表的字段越多,字段的值越大,意味着一个Page能存放的数据量越少,造成数据查询需要加载更多的Page进行更多的IO操作。
2.我们知道磁盘的顺序读写要比随机读写快,但是频繁的插入和删除后,逻辑上相邻的数据可能分散在不同的Page中(数据是以链表形式存放在Page中的)。所以有的时候删除重建索引可以提高查询效率,即:将逻辑上相邻的数据顺序存储在Page上,将随机读写变成顺序读写同时也减少了IO操作。
3.如果我们通过主键id查询某行数据,由于mysql数据本身就是索引,所以只需要执行一次IO;如果我们通过非主键索引查询一个某行数据的某个字段,如果该字段也属于该索引只执行一次IO即可,如果是非索引字段第一次IO取到主键id,第二次IO才是获取数据(这里说的可能有点片面)

4.0 参考借鉴:

MySQL系列:innodb源码分析之表空间管理
MYSQL INNODB数据存储结构
InnoDB INODE 页结构
MySQL InnoDB ibd 文件格式解析(fsp header & xdes entry)


http://chatgpt.dhexx.cn/article/38C31BHa.shtml

相关文章

mysql 里的 ibdata1 文件

为什么 mysql 里的 ibdata1 文件不断的增长&#xff1f; 转自&#xff1a;http://linux.cn/article-5829-rss.html ibdata1 file 我们在 Percona 支持栏目经常收到关于 MySQL 的 ibdata1 文件的这个问题。 当监控服务器发送一个关于 MySQL 服务器存储的报警时&#xff0c;恐慌…

mysql ibdata1

ibdata1是什么&#xff1f; Mysql ibdata1即Innodb data1缩写&#xff0c;是innodb引擎的表空间&#xff0c;用于存放 数据字典Data dictionary&#xff1a; 只读的表&#xff0c;存储对象的相关信息&#xff0c;如占用空间&#xff0c;列的缺省值&#xff0c;约束信息&…

MySQL 中的 ibdata1

系统表空间是InnoDB数据字典、双写缓冲区、更改缓冲区和撤消日志的存储区域 。如果表是在系统表空间中创建的&#xff0c;而不是在每个表文件或通用表空间中创建&#xff0c;则它还可能包含表和索引数据。 系统表空间可以有一个或多个数据文件。默认情况下&#xff0c;ibdata1…

分享篇 | MySQL的ibdata1是个啥,为啥越来越大,怎么缩小?

同事的一个问题&#xff1a; MySQL的ibdata1文件越来越大&#xff0c;这是为啥、 看着别扭&#xff0c;怎么搞小它&#xff1f; ibdata1文件是什么&#xff1f; ibdata1是一个用来构建innodb系统表空间的文件&#xff0c;这个文件包含了innodb表的元数据、undo日志、修改buffe…

js类型转换题

考察隐式类型转换&#xff1a; 1.号一侧出现了字符串&#xff0c;就用String()将不是字符串的变成字符串&#xff0c;最后拼接在一起 2.-号则会调用显示类型转换Number()&#xff0c;将非数字转换成数字&#xff0c;进行计算 true 0 和 true false 都是隐式调用Number()变成…

JS中的强制类型转换

概念 这里我们首先需要知道什么是值类型转换 值类型转换&#xff1a;将值从一种类型转换为另一种类型&#xff0c;就是类型转换&#xff0c;分显示转换和隐式转换 js类型转换出的值都是基本类型&#xff08;number、boolean、string、null、undefined、string&#xff09;&a…

JavaScript——数据类型的转换

目录 一、其他类型转化成字符串类型 1. 把数字型转换为字符串型 变量.toString() 2. 利用 String(变量) 3. 利用 拼接字符串的方法实现转换效果 隐式转换 二、其他类型转化成数字类型&#xff08;重点&#xff09; 1. parseInt(变量) 可以把 字符型的转换为数字型…

JavaScript类型转换规则

类型转换 先梳理一下es6之前有五种基本数据类型:Null、Undefined、String、Number 、Boolean 布尔类型转换规则 直观上为空的值(0、空字符串、null、undefined、和NaN)将变为false 注意 :包含"0" 为true console.log(Boolean("")); //falseconsole.log(…

JavaScript类型转换

javascript是一种弱类型的语言&#xff0c;变量和类型无关&#xff0c;所以有时需要我们进行类型转换 一、数字型转换&#xff08;number&#xff09; 两种方法&#xff1a; 1、number&#xff1a;类型转化走的是v8引擎最底层机制的转化规则&#xff1a; 先将引用类型转化为…

js类型转换

NaNi??? 一、显性类型转换 强制类型转换主要是指通过String、Number和Boolean等构造方法手动转换成对应的字符串、数字和布尔值。 1.1 转为字符串 1.1.1 原始类型转字符串 原始类型字符串string &#xff1a;‘str’“str”number : 123“123”Boolean“true”/“fals…

Axure 9.0.0.3701 授权码

产品经理主力工具 Axure 在2020年5月26日更新了最新的 3701 版本&#xff0c;具体更新如下&#xff1a; 很多小伙伴在更新后会出现之前的授权无法使用的情况&#xff0c;如果出现这种情况大家可以通过在产品栈查找相对应的版本进行获取最新的授权码。 获取地址&#xff1a;http…

Axure 8.0/9.0 注册码 激活码 授权码 License

先查版本号&#xff0c;根据版本号在下面的网址查找对应的授权密钥&#xff08;没有的话&#xff0c;可以试试相近版本&#xff09; https://7rp.cn/34

Axure 9.0.0.3704 授权码

产品经理常用工具软件 Axure 又更新啦&#xff0c;本次更新版本为 Axure RP 9.0.0.3704&#xff0c;具体更新如下&#xff1a; 如何查看版本号&#xff1a; 更新后效果&#xff1a; 很多小伙伴在更新到最新版本后之前的授权出现了失效的情况&#xff0c;下边栈长为大家准备了最…

全网超详细的【Axure】Axure RP 9的下载、安装、中文字体、授权

文章目录 1. 文章引言2. 下载Axure93. 安装Axure94. Axure9中文5. Axure9授权 1. 文章引言 最近在学习原型图&#xff0c;针对画原型图的工具&#xff0c;反复对比墨刀、Axure、xiaopiu后&#xff0c;最终选择了Axure。 接下来&#xff0c;我便从Axure RP 9的下载、安装、中文…

Axure 8授权码

转自&#xff1a;Axure 8.1.0.3372亲测可用授权码 只为记录下 被授权人&#xff1a; zdfans.com 授权密钥&#xff1a; gP5uuK2gHiIVO3YFZwoKyxAdHpXRGNnZWN8Obntqv7FF3pAz7dTu8B61ySxli

Axure RP9授权码

axure rp9安装教程&#xff08;如需免费版安装包请点击此处&#xff09; 1.下载本站提供的压缩包进行解压 2.双击AxureRP-setup9.exe安装程序进行安装 3.点击下一步 4.勾选我同意&#xff0c;点击下一步 5.选择安装位置默认也可以 6.静静的等待安装 7.安装好后点击完成安装&…

combinations()函数(python)

itertools.combinations(iterable, r) 从可迭代对象iterable中选取r个单位进行组合&#xff0c;并返回一个生成元组的迭代器 定义 def combinations(iterable, r):# combinations(ABCD, 2) --> AB AC AD BC BD CD# combinations(range(4), 3) --> 012 013 023 123pool…

Combiner合并案例

Combiner合并案例 需求1. 需求说明2. 文件 案例分析1. 需求分析2. 输入数据3. 期望输出数据4. 实施方案&#xff08;1&#xff09;方案一&#xff08;2&#xff09;方案二 代码实现1. 基于wordcount案例2. 方案一3. 方案二 结果截图 需求 1. 需求说明 统计过程中对每一个MapT…

MapReduce的Combiner详解

核心意义 :减少集群之间的网络开销具体实现步骤 1.自定义一个Combiner 继承 reduce 重写reduce方法2.在 job 中设置:job.setCombinerClass(Combiner类.class) 注意: combiner 能够应用的前提是不能影响最终的业务逻辑&#xff0c;而且&#xff0c;combiner 的输出 kv 应该跟 …

Combiner和Partitioner

Combiner和Partitioner InputFormat & RecordReaders InputFormat 将输出文件拆分为多个 InputSplit,并由 RecordReaders 将 InputSplit 转换为标准的<key,value>键值对,作为 map 的输出。这一步的意义在于只有先进行逻辑拆分并转为标准的键值对格式后,才能为多…