【InnoDB 存储引擎】InnoDB 数据页格式(详细版,数据页格式对于理解索引详细的原理很重要)

news2024/11/25 9:27:16

文章目录

  • 1 InnoDB 数据页结构
    • 1.1 File Header
    • 2.2 Page Header
    • 2.3 Infimum 和 Supremum Record
    • 2.4 User Record 和 Free Space
    • 2.5 Page Directory(InnoDB 数据页结构最重要的部分)
    • 2.6 File Trailer
  • 2 参考资料

1 InnoDB 数据页结构

我们已经知道页是 InnoDB 存储引擎管理数据库的最小磁盘单位。页类型为 B-tree Node 的页存放的即是表中行的实际数据了。在这一节

中,我们将从底层具体地介绍 InnoDB 数据页的内部存储结构

InnoDB 数据页由以下7个部分组成:

  • File Header (文件头)
  • Page Header (页头)
  • Infimun 和 Supremum Records
  • User Records (用户记录,即行记录)
  • Free Space (空闲空间)
  • Page Directory (页目录)
  • File Trailer (文件结尾信息)

其中 File HeaderPage HeaderFile Trailer 的大小是固定的,分别为 38、56、8 字节,这些空间用来标记该页的一些信息,如Checksum,数据页所在B+树索引的层数等。User Records、Free Space、Page Directory这些部分为实际的行记录存储空间,因此大小是动态的。在接下来的各小节中将具体分析各组成部分

1.1 File Header

File Header用来记录页的一些头信息,由下表中的8个部分组成,共占用38字节。

名称大小(字节)说明
FIL_PAGE_SPACE_OR_CHKSUM4该值代表页的checksum值
FIL_PAGE_OFFSET4表空间中页的偏移位。如某独立表空间a.ibd的大小为1GB,如果页的大小为16KB,那么总共有65536个页。FIL_PAGE_OFFSET表示该页在所有页中的位置。若此表空间的ID为10,那么搜索页(10,1)就表示查找表a中的第二个页
FIL_PAGE_PREV4当前页的上一个页,B+ Tree特性决定了叶子节点必须是双向列表
FIL_PAGE_NEXT4当前页的下一个页,B+Tree特性决定了叶子节点必须是双向列表
FIL_PAGE_LSN8该值代表该页最后被修改的日志序列位置LSN (Log Sequence Number)
FIL_PAGE_TYPE2InnoDB存储引擎页的类型,记住0x45BF,该值代表了存放的是数据页,即实际行记录的存储空间
FIL_PAGE_FILE_FLUSH_LSN8该值仅在系统表空间的一个页中定义
FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID4该值代表页属于哪个表空间

以从某 ibd 文件捞出来的 File Header 举例如下:

// 用[]框出来范围
3073 0000c000  [87 b8 54 b1 00 00 00 03  ff ff ff ff ff ff ff ff  |..T.............|
3074 0000c010  00 00 00 00 00 2d 8e d7  45 bf 00 00 00 00 00 00  |.....-..E.......|
3075 0000c020  00 00 00 00 00 27] 00 1a  0d c0 80 66 00 00 00 00  |.....'.....f....|
  • FIL_PAGE_SPACE_OR_CHKSUM

    87 b8 54 b1

  • FIL_PAGE_OFFSE

    00 00 00 03

    偏移量是3说明是表空间的低4页

  • FIL_PAGE_PREV

    ff ff ff ff

  • FIL_PAGE_NEXT

    ff ff ff ff

  • FIL_PAGE_LSN

    00 00 00 00 00 2d 8e d7

  • FIL_PAGE_TYPE

    45 bf

    表明是数据页

  • FIL_PAGE_FILE_FLUSH_LSN

    00 00 00 00 00 00 00 00

  • FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID

    00 00 00 27

2.2 Page Header

接着 File Header 部分的是 Page Header,该部分用来记录数据页的状态信息,由14个部分组成,共占用56字节,如下表所示

名称大小(字节)说明
PAGE_N_DIR_SLOTS2在 Page Directory (页目录)中的 Slot (槽)数。后文重点介绍
PAGE_HEAP_TOP2堆中第一个记录的指针,记录在页中是根据堆的形式存放的
PAGE_N_HEAP2堆中的记录数。一共占用2字节,但是第15位指示行记录格式
PAGE_FREE2指向可重用空间的首指针
PAGE_GARBAGE2已删除记录的字节数,即行记录结构中delete flag为1的记录大小的总数
PAGE_LAST_INSERT2最后插入记录的位置
PAGE_DJRECTION2最后插入的方向。
PAGE_N_DIRECTION2一个方向连续插入记录的数量
PAGE_N_RECS2该页中记录的数量
PAGE_MAX_TRX_ID8修改当前页的最大事务ID,注意该值仅在Secondary Index中定义
PAGE_LEVEL2当前页在索引树中的位置,0x00代表叶节点,即叶节点总是在第0层
PAGE_INDEX_ID8索引ID,表示当前页属于哪个索引
PAGE_BTR_SEG_LEAF10B+树数据页非叶节点所在段的segment header。注意该值仅在B+树的Root页中定义
PAGE_BTR_SEG_TOP10B+树数据页所在段的segment header。注意该值仅在B+树的Root页中定义

2.3 Infimum 和 Supremum Record

这个记录还挺重要的

在InnoDB存储引擎中,每个数据页中有两个虚拟的行记录,用来限定记录的边界。Infimum记录是比该页中任何主键值都要小的值,Supremum指比任何可能大的值还要大的值。这两个值在页创建时被建立,并且在任何情况下不会被删除。在Compact行格式和Redundant行格式下,两者占用的字节数各不相同

2.4 User Record 和 Free Space

User Record就是之前讨论过的部分,即实际存储行记录的内容。再次强调,InnoDB存储引擎表总是B+树索引组织的。Free Space很明显指的就是空闲空间,同样也是个链表数据结构。在一条记录被删除后,该空间会被加入到空闲链表中。

2.5 Page Directory(InnoDB 数据页结构最重要的部分)

Page Directory (页目录)中存放了记录的相对位置(注意,这里存放的是页相对位置,而不是偏移量),

在InnoDB中并不是每个记录拥有一个槽,InnoDB存储引擎的槽是一个稀疏目录(sparse directory),即一个槽中可能包含多个记录。伪记录Intimum的n owned值总是为1,记录Supremum的n owned的取值范围为[1, 8 ],其他用户记录n_owned的取值范围为[4, 8]。当记录被插入或删除时需要对槽进行分裂或平衡的维护操作。

在Slots中记录按照索引键值顺序存放,这样可以利用二叉查找迅速找到记录的指针。假设有(‘i’, ‘d’, ‘c’, ‘b’, ‘e’, ‘g’, ‘l’. ‘h’, ‘f’, ‘j’, ‘k’, ‘a’),同时假设一个槽中包含4条记录,则Slots中的记录可能是:(‘a’, ‘e’, ‘i’)。

由于在InnoDB存储引擎中Page Direcotry是稀疏目录,二叉查找的结果只是一个粗略的结果,因此InnoDB存储引擎必须通过recorder header中的next record来继续查找,相关记录。同时,Page Directory很好地解释了 recorder header中的n owned值的含义, 因为这些记录并不包括在Page Directory中。

这里的 Page Directory 与 InnoDB 行记录中的 record header 联系了起来

如何查找一条记录:

1、先在B+数中找到记录所在的页

2、把页加载入内存

3、通过 Page Directory 进行二叉查找。因为 Page Directory 是稀疏的所有只能找到大概位置。

4、在步骤3的基础上继续根据记录偏移量一行一行的查找

因为步骤3,4都是在内存中的操作,且步骤3是二分查找法,因此通常忽略这部分所消耗的时间

2.6 File Trailer

为了检测页是否已经完整地写入磁盘(如可能发生的写入过程中磁盘损坏、机器关机等),InnoDB存储引擎的页中设置了 File Trailer部分。

File Trailer只有一个FIL_PAGE_END_LSN部分,占用8字节。前4字节代表该页的checksum值,最后4字节和File Header中的FIL PAGE LSN相同。将这两个值与File Header 中的 FIL_PAGE_SPACE_OR_CHKSUM 和 FIL_PAGE_LSN 值进行比较,看 是否一致(checksum的比较需要通过InnoDB的checksum函数来进行比较,不是简单的等值比较),以此来保证页的完整性(not corrupted)

2 参考资料

书籍:《InnoDB 存储引擎》,该书电子版书籍作者无套路免费下载

InnoDB 数据页结构(实验):我的文章:《15.6.1 InnoDB 数据页格式(数据页实验,重要).md》


传送门: 保姆式Spring5源码解析

欢迎与作者一起交流技术和工作生活

联系作者

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

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

相关文章

PS 2023 24.7 Beta Ai 如何解决橙色错误弹窗问题?

距离Adobe软件公司首次将图像编辑及数字绘画软件Photoshop推出到大众面前已经过去35年,最近该公司又再次书写了属于Photoshop的历史新篇章。 Adobe 发布的 Photoshop(Beta)新增「创意填充(Generative Fill)」功能&…

jmter连接mysql数据库取值

测试情况下需要大量的测试数据进行模拟测试,如何使用接口插入大量数据,使用jmter进行插入 步骤如下: 第一步:\lib\ext导入mysql-connector-java-5.1.44-bin.jar驱动 F:\TOOLS\apache-jmeter-5.4.1\apache-jmeter-5.4.1\lib\ext …

Vue的入门学习

Vue 1 Vue概述 通过我们学习的htmlcssjs已经能够开发美观的页面了,但是开发的效率还有待提高,那么如何提高呢?我们先来分析下页面的组成。一个完整的html页面包括了视图和数据,数据是通过请求 从后台获取的,那么意味…

SpringBoot中集成阿里开源缓存访问框架JetCache实现声明式实例和方法缓存

场景 SpringBoot中通过自定义缓存注解(AOP切面拦截)实现数据库数据缓存到Redis: SpringBoot中通过自定义缓存注解(AOP切面拦截)实现数据库数据缓存到Redis_霸道流氓气质的博客-CSDN博客 上面讲的通过自定义注解的方式实现查询数据库数据缓存,除此之外…

数据结构--哈夫曼树

数据结构–哈夫曼树 带权路径长度 结点的 权 \color{red}权 权:有某种现实含义的数值(如:表示结点的重要性等) 结点的带权路径长度 \color{red}结点的带权路径长度 结点的带权路径长度:从树的根到该结点的路径长度(经过的边数)与该结点上权值的乘积 树的…

Element UI组件中el-col、el-row布局学习笔记

一、简介 el-col:列。是Element UI布局中的核心组件,他的作用的将一行分成24个网格,为了方便我们在不同的设备上适配不同的屏幕大小。我们可以通过指定span属性来确定一行中所占的网格数。 el-row:行。包裹在el-col外层&#xf…

【单片机】MSP430f5529单片机,msp430单片机,识别按键单击双击,按键双击判定,驱动程序

文章目录 需求思路介绍程序源码 需求 MSP430f5529单片机的开发板上面只有2个按键硬件,但是通过识别双击,就可以拥有4个按键了! 识别按键,单击P2.1返回1,单击P1.1返回2,双击P2.1返回3,双击P1.1…

第一百零三天学习记录:数据结构与算法基础:算法和算法分析

注:截图转自王卓数据结构教学视频 算法和算法分析 算法的定义 对特定问题求解方法和步骤的一种描述,它是指令的有限序列。其中每个指令表示一个或多个操作。 算法的描述 自然语言:英文、中文 流程图:传统流程图、NS流程图 伪…

辅助驾驶功能开发-功能规范篇(22)-2-L2级辅助驾驶方案功能规范

1.3.2 TSR 系统功能定义 1.3.2.1 状态机 1.3.2.2 状态迁移表 初始状态转移状态转移条件INITOFF系统自检过程中,为 OFF 状态,自检无故障且车辆上次掉电前,为 OFF 状态INITON自检无故障,车辆为首次上电,或者上次掉电之前,系统为非 OFF 状态INITFAILURE系统自检故障,且上…

系统架构设计师-软件工程(4)

一、软件测试 1、软件测试类型(动态测试 / 静态测试) ● 动态测试【计算机运行】 (1)白盒测试法【结构测试】:主要用于单元测试阶段。 a:控制流测试【逻辑覆盖测试(语句覆盖最弱&#…

【数据结构与算法】栈算法题

TS 实现栈 interface IStack<T> {push(e: T): void;pop(): T | undefined;peek(): T;isEmpyt(): boolean;size(): number; }// implements: 实现接口, 一个类可以实现多个接口 class ArrayStack<T> implements IStack<T> {private data: T[] []; // private…

【已解决】词云图只显示方框,无法正确显示中文

文章目录 报错及效果图报错代码解决后效果图 解决方案 报错及效果图 报错代码 from wordcloud import WordCloud def drawing_wordcloud(jieba_split):colormaps colors.ListedColormap([#33b846, #a9be70, #e50000])# 生成词云&#xff08;自定义样式&#xff09;mywc1 Wor…

docker 挂载共享文件夹

docker 挂载共享文件夹 1. 目前不太清楚怎么在已经启动的容器中挂载1.1 也不是完全没办法&#xff0c;把当前的容器打包&#xff0c;再使用-v参数重新启动就可以了 1. 目前不太清楚怎么在已经启动的容器中挂载 1.1 也不是完全没办法&#xff0c;把当前的容器打包&#xff0c;再…

运维面试题

这里写目录标题 TCP介绍一下UDP TCP介绍一下 TCP&#xff08;Transmission Control Protocol&#xff0c;传输控制协议&#xff09;是一种面向连接的、可靠的传输层协议。它在计算机网络中负责提供可靠的数据传输和流量控制。 TCP通过使用三次握手建立一个连接&#xff0c;确…

内存函数相关讲解与模拟实现

目录 memcpy 模拟实现memcpy memmove 模拟实现memmove memcmp 结尾 memcpy 由 source指向地址为起始地址的连续n个字节的数据复制到以destination指向地址为起始地址的空间内。格式如下 void * memcpy ( void * destination, const void * source, size_t num ); 说明…

C语言 — 指针进阶篇(下)

前言 指针基础篇回顾可以详见&#xff1a; 指针基础篇&#xff08;1&#xff09;指针基础篇&#xff08;2&#xff09; 指针进阶篇分为上下两篇,上篇介绍1 — 4&#xff0c;下篇介绍5 — 6 字符指针数组指针指针数组数组传参和指针传参函数指针函数指针数组指向函数指针数组的…

SpringBoot 配置文件:什么是配置文件?配置文件是干什么?

文章目录 &#x1f387;前言1.配置文件的格式2. properties配置文件说明2.1 properties基本语法2.2 读取配置文件 3. yml 配置文件说明3.1 yml 基本语法 4.properties与yml 对比 &#x1f387;前言 学习一个东西&#xff0c;我们先要知道它有什么用处。整个项目中所有重要的数…

C语言,指针易错点

1、封装函数&#xff0c;用指针实现字符串连接 #include <stdio.h> #include <string.h> void MyStrcat(char *dest,char *src) {int i;for(i0;*(desti);i);for(int j0;*(srcj);j)*(desti)*(srcj);*(desti)0; } int main(int argc, const char *argv[]) {char des…

Spring详解(学习总结)

目录 一、Spring概述 &#xff08;一&#xff09;、Spring是什么&#xff1f; &#xff08;二&#xff09;、Spring框架发展历程 &#xff08;三&#xff09;、Spring框架的优势 &#xff08;四&#xff09;、Spring的体系结构 二、程序耦合与解耦合 &#xff08;一&…

MySQL与PostgreSQL的区别

MySQL与PostgreSQL的区别 PostgreSQL的特点包括&#xff1a; 1.PostgreSQL是一个免费的对象-关系数据库服务器 (ORDBMS)&#xff0c;在灵活的BSD许可证下发行。 2.PostgreSQL的Slogan是"世界上最先进的开源关系型数据库"。 3.PostgreSQL具有极高的可靠性&#xff…