【mysql进阶】4-3. 页结构

页面结构

⻚在MySQL运⾏的过程中起到了⾮常重要的作⽤,为了能发挥更好的性能,可以结合⾃⼰系统的业务场景和数据⼤⼩,对⻚相关的系统变量进⾏调整,⻚的⼤⼩就是⼀个⾮常重要的调整项。同时关于⻚的结构也要有所了解,以后介绍的索引原理也是基于⻚实现的。⾸先来看关于⻚的⼏个问题。

1 ⻚的⼤⼩可以设置吗?

分析过程

  • 前⾯介绍了每个数据⻚默认为 16KB ,是操作系统"数据块" 4KB的整数倍,那么只要保证⻚的⼤⼩是操作系统"数据块" ⼤⼩的整数倍是不是也可以呢,答案是肯定的。
  • MySQL提供了⼀个专⻔的系统变量来控制⻚的⼤⼩,可以通过系统变量 innodb_page_size 进⾏调整与查看,在调整⻚⼤⼩的时候需要保证设置的值是操作系统"数据块" 4KB的整数倍,从⽽保证通过操作系统和磁盘交互时"数据块"的完整性,不被分割或浪费,所以规定了innodb_page_size 可以设置的值,分别是 4096 、 8192 、 16384 、 32768 、65536 ,对应 4KB 、 8KB 、 16KB 、 32KB 、 64KB 。

解答问题

  • 可以通过系统变量 innodb_page_size 进⾏调整与查看,但要保证设置的值是操作系统"数据块" 4KB的整数倍,MySQL规定 innodb_page_size 可以设置的值,分别是 4096 、8192 、 16384 、 32768 、 65536 ,对应 4KB 、 8KB 、 16KB 、 32KB 、 64KB 。

2 ⻚都有哪些分类?我们需要重点学习哪种⻚?

  • InnoDB在不同的使⽤场景定义多种不同类型的⻚,常⽤的有 数据⻚ 、 Undo Log⻚ 、Change Buffer⻚ 、 Extent Descriptor(XDES)⻚ 、 InnoDB段信息⻚ 等,每种⻚的数据结构都不相同,其中最需要我们关注的就是数据⻚,由于InnoDB中有个概念叫 “索引即数据”,所以也叫做索引⻚。
  • 不论哪种类型的⻚都具有⻚头(File Header)和⻚尾(File Trailer)两个信息

3 ⻚头和⻚尾具体包含了哪些信息?

解答问题

⻚头和⻚尾中包含的是⽤来描述⽂件相关的信息,如下图所⽰:

image-20241025220920169

  1. ⻚头 - File Header
  • ⻚号: FIL_PAGE_OFFSET 占⽤ 4Byte ,相当于⻚的⾝份证号,通过这个⻓度可以计算出每个InnoDB表中最多可以拥有 2^(48)-1约42亿 个⻚,表空间第⼀个⻚编号从0开始,之后的⻚号分别是1,2,3…依此类推,具体⻚的偏移量计算公式为:⻚号 * 每⻚⼤⼩;那么按照每个⻚默认16KB⼤⼩计算,⼀个表空间最⼤容量为 2^(48) * 16KB = 64TB ,这也是InnoDB表空间最⼤容量是64T的原因;
  • 上⼀⻚⻚号: FIL_PAGE_PREV
  • 下⼀⻚⻚号: FIL_PAGE_NEXT 多个⻚通过这两个信息组成双向链表,即使不同的⻚地址不连续,也可以通过链表连接
  • 表空间ID: FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID ,当前⻚属于哪个表空间
  • ⻚类型: FIL_PAGE_TYPE ,数据⻚对应的⻚类型是 FIL_PAGE_INDEX = 0x45BF
  • 最近⼀次修改的LSN: FIL_PAGE_LSN ,占⽤8Byte
  • 已被刷到磁盘的LSN: FIL_PAGE_FILE_FLUSH_LSN ,占⽤8Byte
  • 校验和: FIL_PAGE_SPACE_OR_CHKSUM ,⽤于⻚的完整性校验
  1. ⻚尾 - File Trailer
  • 最近⼀次修改的LSN

  • 校验和:对应⻚头中的校验和

如果在数据传输的过程中数据丢失或异常中断,导致⼀个数据⻚不完整就可以通过⻚头和⻚尾的校验和进⾏验证,验证算法默认使⽤ CRC32

3.1 什么是LSN?

LSN:是"Log Sequence Number"的缩写,表⽰⽇志序号。⽤⼀个任意的、不断增加的值表⽰⽇志中记录的操作对应的时间点,⽤8字节的⽆符号⻓整形表⽰,后⾯会详细介绍如何⽣成LSN的值

3.2 除了⻚头和⻚尾,数据⻚中还有哪些信息?

  • ⻚头和⻚尾中的各个字段描述了当前⻚的类型以及在⽂件系统中的位置,也就是说通过⻚头可以找到对应的⻚。数据⻚的主要功能是保存数据,在⼀个数据⻚中,除了⻚头与⻚尾占⽤的46个字节之外的空间都⽤来存储真正的数据,也就是数据⾏,数据⾏会与表⾥的数据⾏⼀⼀对应,基于这⼀特性MySQL也被称为 “⾏式数据库” ,也可以把除了⻚头⻚尾的区域称为⻚主体。

3.3 ⻚主体中包含哪些信息?

  • ⻚主体中的信息都是和数据相关的,其中包括刚才提到了数据⾏,还有为了提⾼查询效率的⻚⽬录 Page Directory 和为了⽅便操作和管理数据⻚的数据⻚头 Page Header ,这⼜是三个⾮常重要的概念,接下来我们逐个讨论。

4 数据⾏有哪些信息组成?

分析过程

  • 数据⾏主要存储真实数据,为了⽅便数据的管理与描述,InnoDB在每个数据⾏中还添加了⼀些额外(管理)信息,于是每⼀个 DYNAMIC 数据⾏都可以划分为两部分,⼀部分存储额外信息,⼀部分存储真实数据,额外信息部分包含变⻓字段⻓度列表和NULL值列表两个⼤⼩不确定的区域,以及固定占5字节及40BIT的头信息区域,头信息中存储了⾏的基本信息,包括⾏在⻚内的位置heap_no 、⾏类型 record_type 、下⼀⾏的地址偏移量 next_record 等6项信息,如下图所⽰:

image-20241025222207538

解答问题

  • 数据⾏可以划分为两部分,⼀部分存储额外信息,⼀部分存储真实数据
  • 额外信息部分包含变⻓字段⻓度列表和NULL值列表两个⼤⼩不确定的区域,以及固定占5字节的头信息区域

4.1 数据⾏是如何组织在⼀起的?

  • 数据⾏通过下⼀⾏的地址偏移量,即 next_record 将⻚内所有数据⾏组成了⼀个单向链表,这⾥要注意的是,地址偏移量指向的是下⼀⾏中真实数据的起始地址,这样做的好处是,向右是真实数据,向左就是头信息,⽽⽆需额外的⻓度计算,如图所⽰:

image-20241025222429037

4.2 怎么标识新⻚中的第⼀⾏和最后⼀⾏?

  • 了解了⾏的基本结构和组织⽅式之后,那么当遍历⻚中的⾏时,从哪⾥开始到哪⾥结束呢?为了解决这个问题,每当创建⼀个新⻚,都会⾃动分配两个⾏,⼀个是⾏类型为2的最⼩⾏ Infimun ,heap_no 位置固定为0号,和⼀个是⾏类型为3的最⼤⾏ Supremun , heap_no 位置固定为1号,这两个⾏并不存储任何真实信息,⽽是做为数据⾏链表的头和尾,虽然不存储真实数据,但它们的数据结构和真实数据⾏完全⼀致,只不过数据区域存储的是代表它们⾝份的固定字符串Infimun 和 Supremun ,新⻚中没有数据时,最⼩⾏ Infimun 的 next_record 直接连接最⼤⾏ Supremun ,最⼤⾏不连接任何⾏,它的 next_record 为0;

image-20241025222826954

4.3 当向⼀个新⻚插⼊数据时是如何执⾏的?

  • 当向⼀个新⻚插⼊数据时, heap_no 会从 2 号开始递增,表⽰当前记录在⻚⾯堆中的相对位置;如果是真实数据则 record_type 为0,如果是索引⽬录(B+树⾮叶节点)数据则record_type 为1;再将 Infimun 连接第⼀个数据⾏,最后⼀⾏真实数据⾏连接Supremun ,这样数据⾏就构建成了⼀个单向链表,更多的⾏数据插⼊后,会按照主键从⼩到⼤的顺序进⾏链接;为了使⻚的结构更加清晰,通常将⻚中有数据⾏的区域称为⽤⼾数据区 UserRecords ,把未被数据⾏占⽤的区域称为空闲区 Free Space ,如下图所⽰:

image-20241025223320096

5 如果要查询的数据在某⼀个⻚中,如何定位它在⻚中的位置,⼀条条遍历吗?

分析过程

  • 当然不是,InnoDB使⽤了另⼀种⽅式,更⾼效的查询数据,下⾯我们分析⼀下。

5.1 ⼀条条遍历的查询效率⾼不⾼?

  • 从头开始遍历是⼀个最简单的⽅法,也可以实现数据的查找,当按主键或索引查找某条数据时,从头⾏ infimun 开始,沿着链表顺序逐个⽐对查找,但⼀个⻚有16KB,通常会存在数百⾏数据,每次都要遍历数百⾏,⽆法满⾜⾼效查询。

5.2 如何提⾼⻚内的查询效率?⻚⽬录

  • 为了提⾼查询效率,InnoDB采⽤⼆分查找来解决查询效率问题。
  • 具体实现⽅式是,在每⼀个⻚中加⼊⼀个叫做⻚⽬录 Page Directory 的结构,将⻚内包括头⾏、尾⾏在内的所有⾏进⾏分组,约定头⾏单独为⼀组,其他每个组最多8条数据,同时把每个组最后⼀⾏在⻚中的地址,按主键从⼩到⼤的顺序记录在⻚⽬录中在,⻚⽬录中的每⼀个位置称为⼀个槽,每个槽都对应了⼀个分组,这样在插⼊数据⾏完成链接后,⼀旦最后⼀个分组中的数据⾏超过分组的上限8个时,就会分裂出⼀个新的分组,为了快速判断每个分组是否达到了8个的上限,在每个分组最后⼀⾏中⽤ n_owned 记录了这个分组内的⾏数,与此同时在⻚⽬录中创建⼀个新的槽,后续插⼊的⾏都遵守这个规则;
  • 后续在查询某⾏时,就可以通过⼆分查找,先找到对应的槽,然后在槽内最多8个数据⾏中进⾏遍历即可,从⽽⼤幅提⾼了查询效率;
  • 例如要查找主键为6的⾏,先⽐对槽中记录的主键值,定位到最后⼀个槽2,再从最后⼀个槽中的第⼀条记录遍历,第⼆条记录就是我们要查询的⽬标⾏。

image-20241025224028049

  • 为了提⾼查询效率,在每⼀个⻚中加⼊⼀个叫做⻚⽬录 Page Directory 的结构,采⽤⼆分查找来解决查询效率问题。

6 关于事务、索引这些信息在⻚中怎么记录?

解答问题

  • ⼀张图就可以明确的表⽰出这些信息在⻚中是怎么记录的,如下图所⽰:

image-20241025224259044

7 数据⻚的完整结构是什么样的?

🔍 分析过程

  • 这个问题是对⻚结构的总结性描述,这⾥也⽤⼀张图就可以明确的表⽰出⻚结构的整体信息

  • 注意:这⾥讲的是InnoDB的数据⻚结构,和MyISAM的⻚结构有所不同

✅ 解答问题

  • 下图是数据⻚的完整结构,以及所占的磁盘空间

image-20241025224507457

❤ ⼩结

⾄此⼀个⻚的核⼼结构就介绍完了,主要内容包括:

  1. 设置⻚的⼤⼩

  2. ⻚的主要分类

  3. ⻚头和⻚尾包含的信息

  4. ⻚主体的组成部分

  5. 数据⾏的组成部分

  6. 数据⻚头包含的统计和描述信息

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

HTTP协议讲解

前瞻: 认识URL 1.ipport 2.平时上网,就是进程间通信 3.上网行为,1.获取资源 2.上传数据 相当于I/O 4.http协议采用tcp协议 网页 图片 音乐其实都是资源 Http请求 http request Method:Get/Post资源/路径&#xff1a…

MyBatis缓存详解(一级缓存、二级缓存、缓存查询顺序)

固态硬盘缺陷:无法长时间使用,而磁盘只要不消磁,只要不受到磁影响,就可以长期使用,因此绝大多数企业还是使用磁盘来存储数据 像mysql这种关系型数据库中的数据存储在磁盘中,为方便查询,减少系统…

Linux文件类型和根目录结构

Linux文件类型和根目录结构 1.文件类型 字符文件类型说明~普通文件类似于Windows的记事本d目录文件类似于windows文件夹c字符设备文件串行端口设备,顺序读写,键盘b块设备文件可供存储的接口设备,随机读写,硬盘p管道文件用于进程…

工程项目管理软件怎么选?推荐7款实用工具

本文提及的有主流7款工程项目管理系统软件有: 1. Worktile;2. 广联达BIM5D;3. 泛普软件;4. 明源云工程;5. 飞书;6. Smartsheet;7. Procore。 很多工程项目管理人员常常头疼如何有效地管理多个项目&#xff…

保研考研机试攻略:python笔记(1)

🐨🐨🐨宝子们好呀 ~ 我来更新欠大家的python笔记了,从这一篇开始我们来学下python,当然,如果只是想应对机试并且应试语言以C和C为主,那么大家对python了解一点就好,重点可以看高分篇…

【机器学习】——numpy教程

文章目录 1.numpy简介2.初始化numpy3.ndarry的使用3.1numpy的属性3.2numpy的形状3.3ndarray的类型 4numpy生成数组的方法4.1生成0和1数组4.2从现有的数组生成4.3生成固定范围的数组4.4生成随机数组 5.数组的索引、切片6.数组的形状修改7.数组的类型修改8.数组的去重9.ndarray的…

接口测试(七)jmeter——参数化(RandomString函数)

一、RandomString函数 需求:模拟10个用户注册 1. 【工具】–>【函数助手对话框】 2. 选择RandomString函数 假设手机号码前3位设置为固定数值136,后8位可用RandomString函数随机产生数值 ① Random string length:8(随机长度…

记录element-ui改造select显示为table,并支持多查询条件

最近遇到的一个需求 , 很有趣,是需要一个select组件,要求显示工号,员工姓名,以及区域 三个字段,并且要支持三个字段的查询。显然element原生的组件不适用,这时候我们需要改造一下,把…

基于大数据 Python Vue 美食推荐可视化系统(源码+LW+部署讲解+数据库)

!!!!!!!!! 会持续一直更新下去 有问必答 一键收藏关注不迷路 源码获取:https://pan.baidu.com/s/1aRpOv3f2sdtVYOogQjb8jg?pwdjf1d 提取码: jf1d &#…

Java后端面试题:Java基础篇

目录 Java基础 1.请你说说Java中基本数据类型的bit长度? 2.switch支持哪些数据类型?支持long么? 3.讲一下常见编码方式? 4.char能不能存储中文? 5.为什么数组索引从0开始呢?假如从1开始不行吗&#xf…

w003基于Springboot的图书个性化推荐系统的设计与实现

🙊作者简介:多年一线开发工作经验,原创团队,分享技术代码帮助学生学习,独立完成自己的网站项目。 代码可以查看文章末尾⬇️联系方式获取,记得注明来意哦~🌹赠送计算机毕业设计600个选题excel文…

Git 课程任务

破冰和创建项目 https://github.com/WangXiuhao/loveailab

CORE 安全与身份认证《1》 UseRouting 、UseEndpoints

认证、授权、确权与鉴权 路由 web的请求到达后端服务时,controller(控制器)会处理传入的http请求并响应用户操作, 请求的url会被映射到控制器的操作方法上。 此映射过程由应用程序中定义的路由规则完成。 》》》net core 在中间件中的鉴权授权的位置一…

rtp协议:rtcp包格式和传输间隔

RTP Control Protocol -- RTCP-rtp控制协议 实时传输控制协议(RTCP)基于对会话中的所有参与者定期传输控制包,使用与数据包相同的分发机制。底层协议必须提供数据包和控制包的多路复用,例如使用UDP时使用不同的端口号。RTCP执行四…

Golang | Leetcode Golang题解之第501题二叉搜索树中的众数

题目: 题解: func findMode(root *TreeNode) (answer []int) {var base, count, maxCount intupdate : func(x int) {if x base {count} else {base, count x, 1}if count maxCount {answer append(answer, base)} else if count > maxCount {ma…

一站式学习 Shell 脚本语法与编程技巧,踏出自动化的第一步

文章目录 1. 初识 Shell 解释器1.1 Shell 类型1.2 Shell 的父子关系 2. 编写第一个 Shell 脚本3. Shell 脚本语法3.1 脚本格式3.2 注释3.2.1 单行注释3.2.2 多行注释 3.3 Shell 变量3.3.1 系统预定义变量(环境变量)printenv 查看所有环境变量set 查看所有…

RK3568平台(基础篇)预编译命令原理

一.宏定义(#define)是什么 #define 可以将一对文本进行替换,在编译器读到需要被替换的文本的时候,会将这些文本全部替换成我们给定的文本。 如下是一个宏的定义: #define A 100 二.预编译 预处理命令 #if、#endif、#undef、#ifdef、#else、#elif 在接触#if、#undef这…

图片尺寸怎样能快速修改?图片改尺寸的4款在线工具

图片怎么压缩调整大小呢?现在的图片随着质量或者尺寸都会比较大,在很多平台上传时会导致无法使用,需要按照要求调整图片大小后才能够正常使用,那么如何操作能够快速修改图片大小呢?下面来给大家分享图片改大小的4款在线…

使用virtualenv/Anaconda/Miniconda创建python虚拟环境

自带venv 免安装直接使用 虚拟环境是创建一种隔离的工作空间,在该工作空间中可以安装不同的库,而不影响其他的项目。其中,python自带的venv,就可以很好的创建虚拟环境了。 # 创建虚拟环境 python -m venv venv# windows系统激活…

Linux -- 共享内存(2)

目录 命令 ipcs -m : 命令 ipcrm -m shmid: 共享内存的通信: 为什么共享内存更高效? 代码: ShmClient.cc: ShmServer.cc: 结果: 如何让共享内存实现同步? 代码&a…