InnoDB数据页结构

news2024/10/7 4:31:48

什么是页?什么是数据页?

页是InnoDB管理存储空间的基本单元,一个页的大小一般是16k。

InnoDB有许多不同的页,有存放表空间头部信息的页,INODE信息的页,当然还有存放我们记录信息的页,这个页叫做索引页,也可以叫做数据页。

数据页的结构有哪些?不同的结构分别对应什么功能?

File Header : 页的通用信息

Page Header: 数据页专有的信息

Infimum + supermum : 两个虚拟的行记录
User Records  :存储用户的实际记录,最开始为空,每当我们插入一条记录,都会从Free Space中申请空间划分到此处,然后记录以compact行格式进行存放。
Free Space: 页中尚未使用的空间Page Dictionary :页中某些记录的相对位置
File Tailer : 用来检验页是否完整

为了更好的管理User Records中的记录,InnoDB是怎么操作的?难道不是直接把记录按照指定的格式一条一条简单的摆放在User Records中的吗? compact记录头信息中的那一部分到底做了什么事情?

记录头信息到底做了什么?记录头信息的结构是什么?不同的结构对应的功能是什么?

 预留位置一,二:没有使用

delete_mask :标记该记录是否被删除,占用一个二进制位。 被标记为1的记录被删除掉了,但是还在页面中,被标记为1的记录会组成一个垃圾链表,这个链表被占用的空间被称之为所谓的可重用空间,如果之后有新的记录插入到表中的话,被删除的记录占用的存储空间会被覆盖掉。

min_rec_mask :标记 B+树每层的非叶子节点中的最小记录 (具体什么作用还不清晰)

n_owned: 表示当前记录拥有的记录数量 (具体什么作用还不清晰)

heap_no :表示当前记录在记录堆中的位置信息 ,也可以说是在当前记录页中的位置。 记录之间通过主键可以比大小; 我们插入的数据都是从 2 开始的,0 和 1 分别代表最小记录和最大记录,这两条记录的构造十分简单,都是由5字节大小的记录头信息和8字节大小的一个固定的部分组成的。

record_type :表示当前记录的类型,0代表普通记录,1代表B+树非叶子节点,2代表最小记录,3代表最大记录。

next_record:表示下一条记录的相对位置。

总上所述,记录头信息的作用是:就是把一条一条的记录按照一定的规则联系了起来,而不是我们想的那样只是简单的将用户的记录堆放在User Records中。

next_record这个指针有点儿怪,为什么要指向记录头信息和真实数据之间的位置呢?为什么不干脆指向整条记录的开头位置,也就是记录的额外信息开头的位置呢?

因为这个位置刚刚好,向左读取就是记录头信息,向右读取就是真实数据。我们前面还说过变长字段长度列表、NULL值列表中的信息都是逆序存放,这样可以使记录中位置靠前的字段和它们对应的字段长度信息在内存中的距离更近,可能会提高高速缓存的命中率。

删除一条中间的用户记录会发生哪些变化?

1.该记录没有从存储空间中移除,而是把这条记录的delete_mask值设置为1

2. 该条记录的next_record值变成了0,意味着该条记录并没有下一条记录了

3.该条记录的前一个记录的next_record指向了该条记录的后一个记录

4. 最大记录只n_owned值从5变成了4

页目录(page Directory)是什么?是为了解决什么问题?

在页中,所有的记录是通过单链表的形式连接在一起,如果我们想要查询下面的记录,c1是主键

SELECT * FROM page_demo WHERE c1 = 3;

最笨的方法是从Infimum记录开始,然后沿着单链表一直查下去,直到查出来符合条件的结果,或者直接查不出来。 如果表中的数据特别多的话,再这样一条一条记录的查找就不行了。 

我们可以设置一个目录,然后我们如果想要查找某一条记录的时候,先看一下目录,然后查找内容。

InnoDB也做了一个类似的目录:

1. 将所有的记录(不包括被删除的记录)分为几个组。

2. 每个组的最后一条记录,也就是组内最大的那条记录 的头信息中的n_owned属性表示该条记录中拥有多少记录,也就是组内有多少条记录。

3. 把组内最后一条记录的地址偏移量单独提取出来按照顺序存储在靠近页的尾部的地方,这个地方就是 Page Directiory,也就是页目录。

页面中的目录的地址偏移量被称为槽,页目录也就是槽组成的。

 上面的图中,为什么最小记录的n_owned的值为1,而最大记录的n_owned的记录是5呢? 

InnoDB对于每个组的记录条数是有规定的:对于最小记录所在的分组只能有一个记录,最大记录所在的分组可以有1-8条记录,剩下的分组中的记录条数只能是4-8 条之间。

具体分组是按照下面的步骤进行的:

初始情况只有两组,每组中只有一条记录,分别是最小记录和最大记录。

之后每次插入一条数据,都会页目录中找到主键值比本记录的主键值大,并且差值最小的槽,然后把该槽的对应的记录的n_owned记录值+1 ,表示本组内添加了一条记录,直到改组中的记录数量等于8 个。

在一个组中的记录数量等于8后,再插入一条数据,那个这个组将被拆分为两个组,一个组四条记录,一个组是五条记录,这个过程会在页目录中新增一个槽来记录这个新增分组的最大的那条记录的偏移量。

 

不要忘记,我们最初都是为了通过主键来定位一条数据。现在我们有了页目录,我们开始定位这条数据了。

假如说我们想要定位主键是6的数据,我们需要进行如下操作

设置low 为0 ,high 是4

先找到中间槽对应的主键:中间槽是(0+4)/ 2 = 2 ,槽2 对应的主键是8 ,8  > 6 ,设置high = 2 ,low不变

然后再计算中间槽 (0 + 2) = 1 ,槽1对应的主键是4 , 4 < 6 ,设置low = 1 

此时higt - low 的值是1 ,所以 该主键就是在第high个组内 ,也就是槽2中 。 然后我们只需要找到槽2中主键最小的那条记录,然后沿着单向链表遍历槽2即可找到数据。  

还有一个问题是我们现在知道该条记录是在槽2中的,同时我们也知道了槽2的最大主键记录,但是我们其实是从槽2的最小记录开始遍历,这个时候该怎么找到槽2的最小记录呢? 

正确做法是,我们可以先拿到刚才记录出来的槽1,然后拿到槽1的最大记录,槽1和槽2是互相紧邻的,然后往后一下,就是槽2的最小记录了。 

总结一下,在一个数据页中查找主键值的记录的过程分为两步:

1. 通过二分法确定该记录所在的槽的位置,并找到该槽中主键值最小的那条记录。 

2. 通过next_record 属性遍历该槽所在的组中的各个记录。 

综上所述,目录页的作用就是把User Record中分组的数据安装索引一一对应起来,方便通过主键进行数据的查找。

Page Header(页面头部)是干什么的?

记录数据页中存储的记录的状态信息,比如说本页中存储了多少条记录,第一条记录的地址是什么? 页目录中存储了多少个槽 ? Page Header也页的第二部分,占用固定的56个字节。

 

File Header (文件头部)是干什么的?

之前介绍的Page Header是专门针对数据页的,不是所有页特有的,现在的File Header文件头部是公有的,也就是说,不同类型的页都会有个File Header 部分,并且作为第一组成部分,File Header记录是一些针对各种页都通用的信息,比如说,此页的编号,他的上一个页,下一个页是谁等等,固定38个字节。

 FIL_PAGE_SPACE_OR_CHKSUM 是页面的校验和,用来把长的字符串通过一定的算法转化成比较短的值,到时候比较的时候,不再直接把字符串进行比较,而是使用校验和来进行比较,从而提升性能。

Fil_PAGE_OFFSET:页的号码,就像身份中一样,通过页号定位一个页。

FIL_PAGE_TYPE : 页的类型,除了我们上面一直说的索引页(也叫数据页),还有其他好多类型

FIL_PAGE_PREV 和 FIL_PAGE_NEXT ,数据非常多的时候,是被存储在不同的页中,页在物理空间上并不相邻,这个时候InnoDB是同过双向链表把页给连接起来的,这个两个字段就是连接的字段。

 File Trailer

用来检验页面是否完整。

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

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

相关文章

【苹果】Apple Store 更换ID教程

在此之前需要准备的项目&#xff1a; 一台苹果手机【教程环境&#xff1a;ios15 in iPhone11】一个新的苹果ID账号一个具备完整阅读能力愿意看完教程的人 教程开始 第一步&#xff1a;解锁您的 iPhone 第二步&#xff1a;打开你的应用商店 第三步&#xff1a;点击右上角头像…

Linux驱动快速入门(vscode的使用)

vscode精确跳转前提&#xff1a; 1、安装了clangd插件 2、禁止了c/c intellisense&#xff1a; 3、在Linux内核源码首目录下有compile_commands.json文件&#xff0c;且这个文件内容“cc”改为了“xxxx-gcc”&#xff0c;后先清理之前编译的&#xff0c;后用bear make编译。…

ChatGPT官方APP上线:速度极快且免费、增加语音识别,网友:真香

安卓版也马上要来。 很强大&#xff0c;很简洁&#xff0c;而且它太快了。 这就是人们对几小时前 OpenAI 发布的 ChatGPT 官方版 App 的评价&#xff1a; ChatGPT 推出近半年以来&#xff0c;已经从新鲜的事物成为改变整个科技领域的推手。有机构统计认为&#xff0c;早在今年…

【手撕代码系列】JS手写实现深拷贝

公众号&#xff1a;Code程序人生&#xff0c;分享前端所见所闻 深拷贝是在计算机科学中非常重要的概念&#xff0c;尤其是在处理数据结构和对象的时候。深拷贝的目的是创建一个新的对象&#xff0c;它有自己的内存空间&#xff0c;并且其中的所有值都是原始对象的副本。这样做的…

某大型啤酒企业:CACTER邮件网关成功替换IronPort!安全防护升级

客户案例 某大型啤酒厂商的公司规模和市场份额多年来始终都处于行业领先地位&#xff0c;积极赞助多项体育赛事&#xff0c;持续丰富和提升品牌形象。 作为一家具有全球影响力的企业&#xff0c;自然也成为了全球黑客等攻击团伙的重点目标&#xff0c;而系统攻击的开端便是钓…

互联网医院牌照的申请流程|互联网医院资质申请难吗

互联网医院系统现在已经发展的很成熟了&#xff0c;国家也出台了很多鼓励的相关政策&#xff0c;所以很多的医疗机构也纷纷的开始开发互联网医院系统&#xff0c;当然要想互联网医院系统能够正常的运行看诊&#xff0c;还需要申办互联网医院牌照&#xff0c;接下来给大家介绍一…

GE Hydran M2 监测各种故障气体的综合值

Hydran M2 是一种紧凑型永久安装在线变压器监测设备&#xff0c;可在出现故障情况时向人员发出警报。它持续监测各种故障气体的综合值&#xff08;以 ppm 为单位&#xff09;或仅监测氢气值&#xff08;取决于购买的传感器&#xff09;。此外&#xff0c;它还跟踪油中的水分&am…

Redis自学之路—基础数据结构(二)

目录 简介 Redis应用场景 Redis基础数据结构 一、string&#xff08;字符串&#xff09; string类型相关指令 二、list&#xff08;列表&#xff09; list类型相关指令 三、hash&#xff08;字典&#xff09; hash类型相关指令 四、set&#xff08;集合&#xff09; se…

Mysql多表和窗口函数

1.多表查询--自关联查询 # 格式: select * from A join A on 条件; 或者 select * from A left join A on 条件; # 自关联查询的用法和 内连接, 外连接等操作一模一样, 只不过是: 表自己关联自己. # 应用场景: 分类表(多级), 行政区域表(3级, 省市区). # 查询结果: 跟上述多…

一起来学shiny把(2)—-shiny页面布局

什么是shiny&#xff1f;Shiny是一个R包&#xff0c;可让您轻松地直接从 R 构建交互式 Web 应用程序&#xff08;应用程序&#xff09;。本系列是个长教程&#xff0c;带你由浅入深学习shiny。 上一节我们在文章《R语言系列教程—–一起来学shiny吧&#xff08;1&#xff09;》…

什么是语音识别的语音搜索?

前言 随着智能手机、智能音箱等智能设备的普及&#xff0c;语音搜索已经成为了一种趋势。语音搜索不仅方便快捷&#xff0c;而且可以实现双手的解放。语音搜索的实现离不开语音识别技术&#xff0c;本文将详细介绍语音识别的语音搜索。 语音识别的基本原理 语音识别是将语音信…

高光谱图像处理的spectral模块一些用法

目录 1、安装 2、读取高光谱图像 3、显示高光谱图像 4、spectral的特点 5、标签图显示 6、标签、地物融合显示 8、显示三维立方体 9、保存图像 1、安装 pip install spectral -i https://pypi.tuna.tsinghua.edu.cn/simple 2、读取高光谱图像 # -*- coding:utf-8 _*…

react笔记_14在react中使用echarts

目录 echarts官网在项目引入echarts[1]下载[2-1] 全量引入[2-2]按需引入问题 - 仅引入核心模块 图表配置[1] 柱状图(bar)横/纵向柱状图 [2] 漏斗图(funnel)漏斗图的形状 echarts官网 echarts官网 在项目引入echarts [1]下载 npm install echarts [2-1] 全量引入 import *…

FPGA_学习_05_管脚约束

前言&#xff1a;就初学管脚约束相关知识而言&#xff0c;内容还不足以构成饱满的文章。 但管脚约束是一个独立的内容&#xff0c;它是值得有一篇单独的博客的。若后续学习了管脚约束新的知识&#xff0c;则进一步扩充本篇博客内容。 1 XDC基础语法 Vivado的管脚约束文件用XDC…

易基因:m5C高甲基化介导EGFR突变的非小细胞肺癌耐药潜在机理|国人佳作

大家好&#xff0c;这里是专注表观组学十余年&#xff0c;领跑多组学科研服务的易基因。 对EGFR酪氨酸激酶抑制剂&#xff08;EGFR-TKI&#xff09;的固有耐药&#xff08;Intrinsic resistance&#xff09;和获得耐药(acquired resistance)是EGFR突变型非小细胞肺癌(NSCLC)患…

当上了小领导如何管理手下员工才能最高效的工作?

公司新建了一个项目&#xff0c;我负责招人并管理&#xff0c;之前没有正式的管理经验&#xff0c;如何才能更好的管理新人&#xff0c;快速推进工作&#xff1f; 在公司新建项目时&#xff0c;担任小领导的你需要负责招人和管理团队成员。作为一个没有正式管理经验的人&#x…

Elsevier Ocean Engineering Guide for Authors 解读

文章目录 ★Types of contributions★Submission checklistEthics in publishing★Declaration of competing interestDeclaration of generative AI in scientific writingSubmission declaration and verificationPreprint posting on SSRNUse of inclusive languageReportin…

vue-antd-admin加载动态菜单的步骤——vue3动态菜单——技能提升

最近在写后台管理系统时&#xff0c;发现老系统有个需求&#xff0c;就是动态加载菜单 以往的静态菜单&#xff1a;路由都放在router/config.js中&#xff0c;菜单页面放在pages里面。 加载的动态菜单&#xff1a;路由是通过接口获取&#xff0c;然后加载到路由中&#xff0c…

凌恩生物美文分享 | Nature教你如何深入开展植物基因组研究,看这篇绝对够!

自三代测序技术面世以来&#xff0c;基因组的相关研究迈上了一个新台阶&#xff0c;无论是完整性、连续性、准确性较二代测序技术组装基因组均有较大的提升。凌恩生物也紧随前沿&#xff0c;整合多种优势技术及信息分析平台&#xff0c;涵盖Illumina&#xff0c;Pacbio等多种测…

阿里主动改革,再次引领国内公司治理新浪潮

北京时间2023年5月18日美股盘前&#xff0c;阿里公布2023财年Q4及全年财报&#xff0c;整体财务状况符合市场预期&#xff0c;但推动组织变革的进度&#xff0c;却给了市场一个“惊喜”。 财报中&#xff0c;阿里宣布了整体组织变革背景下&#xff0c;旗下数个业务的未来方向&…