MYSQL08_页的概述、内部结构、文件头、文件尾、最大最小记录、页目录、区段表

news2024/11/25 22:35:52

文章目录

  • ①. 页的概述、大小
  • ②. 页的内部结构
  • ③. 第一部分 - 文件头
  • ④. 第一部分 - 文件尾
  • ⑤. 第二部分 - 空闲、用户记录、最大最小
  • ⑥. 第三部分 - 页目录
  • ⑦. 第三部分 - 页面头部
  • ⑧. 从数据页角度看B+树
  • ⑨. 区、段和表、碎片区

①. 页的概述、大小

  • ①. 数据库的存储结构:页
  1. 索引结构给我们提供了高效的索引方式,不过索引信息以及数据记录都是保存在文件上的,确切来说是存储在页结构中。另一方面,索引是在存储引擎中实现的,MySQL服务器上的存储引擎负责对表中数据的读取和写入工作。不同的存储引擎中存放的格式一般是不同的,甚至有的存储引擎Memory都不用磁盘来存储数据
  2. 由于InnoDB是MySQL的默认存储引擎,所以本章节讲解InnoDB存储引擎的数据存储结构
  • ②. 磁盘与内存交互的基本单位:页
  1. InnoDB将数据划分为若干个页,InnoDB中页的默认大小为16KB
  2. 以页作为磁盘和内存之间交互的基本单位,也就是一次最少从磁盘中读取16KB的内容到内存中,一次最少把16KB的内容刷新到磁盘中
  3. 在数据库中,不论读一行,还是读多行,都是将这些行所在的页进行加载。也就是说数据库管理存储空间的基本单位是页,数据库I/O操作的最小单位也是页。一个页中可以存储多个行记录
    注意:记录是按照行来储存的,但是数据库的读取并不以行为单位,否则一次读取(也就是一次I/O操作),只能处理一行数据,效率会非常的低
  • ③. 页结构概述
  1. 页a、页b、页c,这些页可以不在物理结构上相连,只要通过双向链表相关联即可
  2. 每个数据页中的记录会按照主键值从小到大的顺序组成一个单向链表,每个数据页都会为存储在它里边的记录生成一个页目录
  3. 在通过主键查找某条记录的时候可以在页目录中使用二分法快速定位到对应的槽
    在这里插入图片描述
  • ④. 页的大小
    不同数据库管理系统的页大小不同,MySQL的InnoDB存储引擎中,默认的页大小是16KB
    SQL Server中页的大小为8kb,而在Oracle中我们用术语"块"来代表页,Oracke支持的块大小为2kb、4kb、8kb、16kb、32kb、64kb
mysql> show variables like '%innodb_page_size%';
+------------------+-------+
| Variable_name    | Value |
+------------------+-------+
| innodb_page_size | 16384 |
+------------------+-------+
  • ⑤. 页的上层结构,在数据库中还存在着区、段、和表空间的概念
  1. 区(Extent)是比页大一级的存储结构,在InnoDB存储引擎中,一个区会分配64个连续的页。因为InnoDB中的页大小默认是16KB,所以一个区的大小是64 * 16KB = 1MB
  2. 段(Segment)由一个或多个区组成,区在文件系统是一个连续分配的空间(在InnoDB中是连续的64个页),不过在段中不要求区与区之间是相邻的。段是数据库中分配单位,不同类型数据库对象以不同的段形式存在。当我们创建数据表、索引的时候,就会响应创建对应的段,比如创建一张表时会创建一个表段,创建一个索引时会创建一个索引段
  3. 表空间(Tablespace)是一个逻辑容器,表空间储存的对象是段,在一个表空间中可以有一个或多个段,但是一个段只能属于一个表空间。数据库由一个或多个表空间组成,表空间从管理上可以划分为系统表空间、用户表空间、撤销表空间、临时表空间
    在这里插入图片描述

②. 页的内部结构

  • ①. 页按照类型划分,常见的有数据页(保存B+树节点)、系统页、Undo页和事务数据页等。数据页是我们最常使用的页,页结构示意图如下:
    在这里插入图片描述
  • ②. 数据页16KB大小的存储空间被划分为七个部分,分别是文件头、页头、最大最小记录、用户记录、空闲空间、页目录和文件尾,如下图所示

在这里插入图片描述

③. 第一部分 - 文件头

  • ①. File Header:描述各种页的通用信息。比如页的编号、其上一页、下一页是谁等、大小为38字节

  • ②. File Header文件头部具体构成
    在这里插入图片描述

  • ③. FIL_PAGE_OFFSET:每一个页都有一个单独的页号,就跟你的身份证号码一样,InnoDB通过页号可以唯一定位一个页

  • ④. FIL_PAGE_TYPE:代表当前页的类型
    在这里插入图片描述

  • ⑤. FIL_PAGE_PREV和FIL_PAGE_NEXT
    InnoDB都是以页为单位存放数据的,如果数据分散到多个不连续的页中存储的话需要把这些页关联起来,FIL_PAGE_PREV和FIL_PAGE_NEXT就分别代表本页的上一个和下一个页的页号。这样通过建立一个双向链表把许许多多的页就都串联起来了,保证这些页之间不需要是物理上的连续,而是逻辑上的连续
    在这里插入图片描述

  • ⑥. FIL_PAGE_SPACE_OR_CHKSUM:代表当前页面的校验和checksum

  1. 文件头部和文件尾部都有属性:FIL_PAGE_SPACE_OR_CHKSUM
  2. 什么是校验和?对于一个很长的字节串来说,我们会通过某种算法来计算一个比较短的值来代表这个很长的字节串,这个比较短的值就称为校验和
  3. 在比较两个很长的字节串之前,先比较这两个长字节串的校验和,如果校验和都不一样,则两个长字节串肯定是不同的,所以省去了直接比较两个比较长的字节串的时间损耗
  • ⑦. 校验和的作用
  1. InnoDB存储引擎以页为单位把数据加载到内存中处理,如果该页中的数据在内存中被修改了,那么在修改后的某个时间需要把数据同步到磁盘中。但是在同步了一半的时候断电了,造成了该页传输的不完整
  2. 为了检测一个页是否完整也就是在同步的时候有没有发生只同步一半的尴尬情况,这时可以通过文件尾的校验和checksum值与文件头的校验和做比对,如果两个值不相等则证明页的传输有问题,需要重新进行传输,否则认为页的传输已经完成
  • ⑧. 校验和举例子
  1. 每当一个页面在内存中修改了,在同步之前就要把它的校验和算出来,因为File Header在页面的前边,所以校验和会被首先同步到磁盘,当完全写完时,校验和也会被写到页的尾部,如果完全同步成功,则页的首部和尾部的校验和应该是一致的
  2. 如果写了一半儿断电了,那么在File Header中的校验和就代表着已经修改过的页,而在File Trailer中的校验和代表着原先的页,二者不同则意味着同步中间出了错。这里,校验方式就是采用 Hash 算法进行校验
  • ⑨. FIL_PAGE_LSN:页面被最后修改时对应的日志序列位置英文名是:Log Sequence Number

④. 第一部分 - 文件尾

  • ①. 大小8字节
  1. 前4个字节代表页的校验和:这个部分是和File Header中的校验和相对应的
  2. 后4个字节代表页面被最后修改时对应的日志序列位置LSN:这个部分也是为了校验页的完整性的,如果首部和尾部的LSN值校验不成功的话,就说明同步过程出现了问题
  • ②. 文件头部和文件尾部都有属性:FIL_PAGE_SPACE_OR_CHKSUM

⑤. 第二部分 - 空闲、用户记录、最大最小

  • ①. 页的主要作用是存储记录,所以 “最大和最小记录” 和 “用户记录” 部分占了页结构的主要空间
    在这里插入图片描述
  • ②. Free Space (空闲空间)
    我们自己存储的记录会按照指定的行格式存储到User Records部分。但是在一开始生成页的时候,其实并没有User Records这个部分,每当我们插入一条记录,都会从Free Space部分,也就是尚未使用的存储空间中申请一个记录大小的空间划分到User Records部分,当Free Space部分的空间全部被User Records部分替代掉之后,也就意味着这个页使用完了,如果还有新的记录插入的话,就需要去申请新的页了

在这里插入图片描述

  • ③. User Records中的这些记录按照指定的行格式一条一条摆在User Records部分,相互之间形成单链表

  • ④. Infimum + Supremum(最小最大记录)
    InnoDB规定的最小记录与最大记录这两条记录的构造十分简单,都是由5字节大小的记录头信息和8字节大小的一个固定的部分组成的,如图所示
    在这里插入图片描述
    在这里插入图片描述

⑥. 第三部分 - 页目录

  • ①. 为什么需要页目录?
    在页中,记录是以单向链表的形式进行存储的。单向链表的特点就是插入、删除非常方便,但是检索效率不高,最差的情况下需要遍历链表上的所有节点才能完成检索。因此在页结构中专门设计了页目录这个模块,专门给记录做一个目录,通过二分查找法的方式进行检索,提升效率

  • ②. 需求:根据主键值查找页中的某条记录,如何实现快速查找呢?

SELECT * FROM page_demo WHERE c1 = 3;

方式1:顺序查找
从Infimum记录(最小记录)开始,沿着链表一直往后找,总有一天会找到(或者找不到),在找的时候还能投机取巧,因为链表中各个记录的值是按照从小到大顺序排列的,所以当链表的某个节点代表的记录的主键值大于你想要查找的主键值时,你就可以停止查找了,因为该节点后边的节点的主键值依次递增(如果一个页中存储了非常多的记录,这么查找性能很差)
方式2:使用页目录,二分法查找

  1. 将所有的记录分成几个组,这些记录包括最小记录和最大记录,但不包括标记为“已删除”的记录。
  2. 第1组,也就是最小记录所在的分组只有1个记录;
    最后一组,就是最大记录所在的分组,会有1-8条记录;
    其余的组记录数量在4-8条之间
    这样做的好处是,除了第1组(最小记录所在组)以外,其余组的记录数会尽量平分
  3. 在每个组中最后一条记录的头信息中会存储该组一共有多少条记录,作为n_owned字段。
  4. 页目录用来存储每组最后一条记录的地址偏移量,这些地址偏移量会按照先后顺序存储起来,每组的地址偏移量也被称之为槽(slot),每个槽相当于指针指向了不同组的最后一个记录
    在这里插入图片描述
  • ③. 现在的page_demo表中正常的记录共有6条,InnoDB会把它们分成两组,第一组中只有一个最小记录,第二组中是剩余的5条记录。如下图
  1. 现在页目录部分中有两个槽,也就意味着我们的记录被分成了两个组,槽1中的值是112,代表最大记录的地址偏移量(就是从页面的0字节开始数,数112个字节);槽0中的值是99,代表最小记录的地址偏移量
  2. 注意最小和最大记录的头信息中的n_owned属性
    最小记录的n_owned值为1,这就代表着以最小记录结尾的这个分组中只有1条记录,也就是最小记录本身
    最大记录的n_owned值为5,这就代表着以最大记录结尾的这个分组中只有5条记录,包括最大记录本身还有我们自己插入的4条记录

在这里插入图片描述
在这里插入图片描述

  • ④. 在一个数据页中查找指定主键值的记录的过程分为两步(非常重要)
  1. 通过二分法确定该记录所在的槽,并找到该槽所在分组中主键值最小的那条记录
  2. 通过记录的next_record属性遍历该槽所在的组中的各个记录

⑦. 第三部分 - 页面头部

  • ①. 为了能得到一个数据页中存储的记录的状态信息,比如本页中已经存储了多少条记录,第一条记录的地址是什么,页目录中存储了多少个槽等等,特意在页中定义了一个叫Page Header的部分,这个部分占用固定的56个字节,专门存储各种状态信息
    在这里插入图片描述

  • ②. PAGE_DIRECTION:假如新插入的一条记录的主键值比上一条记录的主键值大,我们说这条记录的插入方向是右边,反之则是左边。用来表示最后一条记录插入方向的状态就PAGE_DIRECTION

  • ③. PAGE_N_DIRECTION:假设连续几次插入新记录的方向都是一致的,InnoDB会把沿着同一个方向插入记录的条数记下来,这个条数就用PAGE_N_DIRECTION这个状态表示。当然,如果最后一条记录的插入方向改变了的话,这个状态的值会被清零重新统计

⑧. 从数据页角度看B+树

  • ①. 一颗B+树按照节点类型可以分成两部分
  1. 叶子节点,B+树最底层的节点,节点的高度为0,储存行记录
  2. 非叶子节点,节点的高度大于0,储存索引键和页面指针,并不储存行记录本身
    在这里插入图片描述
  • ②. B+树是如何进行记录检索的呢
    从B+树的跟几点开始,逐层检索,在哪个目录项里面,进行定位到具体的页,将数据页加载到内存中,页目录中的槽(slot)采用二分查找的方式找到一个粗略的记录分组,找到最小的那条记录,通过next_record遍历查找记录

  • ③. 普通索引和唯一索引在查询效率上有什么不同?
    唯一索引就是在普通索引上增加了约束性,也就是关键字唯一,找到了关键字就停止检索。而普通索引,可能会存在用户记录中的关键字相同的情况,根据页结构的原理,当我们读取一条记录的时候,不是单独将这条记录从磁盘中读出去,而是将这个记录所在的页加载到内存中进行读取。InnoDB储存引擎的页大小为16KB,在一个页中可能存储着上千条记录,因此在普通索引的字段上进行查找页就是在内存中多几次"判断下一条记录"的操作,对于CPU来说,这些操作所消耗的时间是可以忽略不计的。所以对一个索引字段进行检索,采用普通索引还是唯一索引在检索效率上基本上没差别

⑨. 区、段和表、碎片区

  • ①. 为什么要有区?
  1. B+树的每一层中的页都会形成一个双向链表,如果是以页为单位来分配存储空间的话,双向链表相邻的两个页之间的物理位置可能离的非常远,如果需要范围查询的话只需要定位最左边和最右边的记录,沿着双向链表一直扫描即可,而如果两个页之间的物理位置隔得非常远,就是所谓的随机I/O,这是非常慢的,所以应该尽量让链表中相邻页的物理位置页相邻,这样进行范围查询时才可以使用所谓的顺序I/O
  2. 这就引入了的概念,一个区就是在物理位置上连续的64个页,因为InnoDB的页大小默认是16KB,所以一个区的大小是1MB。在表中数据量大的时候,为某个索引分配空间的时候就不再按照页为单位分配了,而是按照区为单位分配,甚至在表中数据特别多的时候,可以一次性分配多个连续的区。虽然可能造成一点点空间的浪费,但是从性能角度看,可以消除很多随机I/O

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

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

相关文章

小行星碰撞

题目链接 小行星碰撞 题目描述 注意点 两个小行星相互碰撞,较小的小行星会爆炸如果两颗小行星大小相同,则两颗小行星都会爆炸每一颗小行星以相同的速度移动正负表示小行星的移动方向(正表示向右移动,负表示向左移动&#xff09…

day81 session会话 文件上传

知识点: session 文件上传 一 session 1)session:会话 在服务器端存储信息 指客户与服务器的会话 当用户通过浏览器访问服务器的某个页面时,在服务器开辟一个内存空间session 每个session 有唯一的id 2)session过期 …

安全开发实战(3)--存活探测与端口扫描

目录 安全开发专栏 前言 存活探测 端口扫描 方式一: 1.3.1 One 1.3.2 Two 1.3.3 批量监测 方式二: 1.3.1 One 1.3.2 Two 1.3.3 Three 1.3.4 扫描ip地址,提取出开放端口和协议 ​编辑 1.3.5 批量扫描(最终完成版) 总结 安全开发专栏 安全开发实战​http://t.csd…

javaee前后端交互

1.选择Java Enterprise创建项目 2.勾选Web Profile 3.项目名称 4.创建包和类 5.继承HttpServlet并重写方法doGet和doPost 6.在web.xml里添加代码 7.点击Add Configuration,进去后点击加号 8.选择选项 9.调整如图,后选择Deployment进入 10.点击加号选择第一个 11.…

【GoWeb框架初探————Gin篇】

1. Gin 1.1 下载相应依赖 创建go项目,在项目下建立go.mod文件(若有则跳过) 命令行运行 go get github.com/gin-gonic/gin1.2 启动一个简单Web服务 package mainimport ("github.com/gin-gonic/gin""github.com/thinkerou/…

如何正确查看容器的CPU使用率

进入容器中top,虽然看到的PID是容器的,但是%Cpu的统计信息却是宿主机的。 如图 原理 进程的cpu使用率是如何计算出来的? 每个进程的状态是放在文件里的,在/proc目录下,每个进程有自己pid命名的文件夹, …

vscode 如何支持点击函数跳转

一、配置方式 我要配置的是 python 语言,以 python 语言为例来设置 1、在扩展商店搜索 python 并安装 2、安装完成后点击设置按钮,进入扩展设置 3、在扩展设置中搜索 go to definition,将下面红框的两项设置为 goto 4.连接远程服务器后还需…

基于go+vue的多人在线聊天的im系统

基于govue的多人在线聊天的im系统 文章目录 基于govue的多人在线聊天的im系统一、前端部分二、后端部分1、中间件middleware设计jwt和cors2、配置文件设计3、Mysql和Redis连接4、路由设计5、核心功能设计 一、前端部分 打算优化一下界面,正在开发中。。。 二、后端…

软件测试入门学习笔记

系统测试流程规范 一.研发模型 1.瀑布模型 从可行性研究(或系统分析)开始,需求 2.增量迭代模型 3.敏捷开发模型 二.质量模型

神经网络中正则化和正则化率的含义

在神经网络中,正则化是一种用于防止模型过拟合的技术。过拟合是指模型在训练数据上表现得很好,但是对于未见过的新数据,其泛化能力却很差。正则化通过在损失函数中添加一个额外的项来惩罚模型的复杂度,从而鼓励模型学习更加简单、更加泛化的特征。 正则化的含义 正则化通常…

如何修改WordPress数据库表前缀以提高安全性

WordPress作为世界上最受欢迎的内容管理系统之一,吸引了数以百万计的用户。然而,正因为其广泛的使用,WordPress网站也成为了黑客攻击的目标之一。其中一个最常见的安全漏洞是使用默认的数据库表前缀wp_,使得黑客能够更轻松地进行大…

引导过程和服务控制

目录 一.Linux操作系统的引导过程 1.开机自检(BIOS): 2.MBR引导: 3.启动GRUB菜单: 4.加载Linux内核 5.init进程初始化 二.系统初始化进程 1.init 进程 2.Systemd 2.1 systemd 概述 2.2 Systemd 与 传统 Sy…

设计千万级并发系统架构需要考虑的各方面因素

设计千万级并发系统架构需要考虑多方面因素,包括系统的可伸缩性、高可用性、性能、安全性等。 1、分布式架构: 使用微服务架构:将系统拆分成多个独立的服务,每个服务都可以独立部署和扩展。 使用分布式服务框架:如S…

Unity类银河恶魔城学习记录12-11 P133 Merge Skill Tree with Parry skill源代码

Alex教程每一P的教程原代码加上我自己的理解初步理解写的注释,可供学习Alex教程的人参考 此代码仅为较上一P有所改变的代码 【Unity教程】从0编程制作类银河恶魔城游戏_哔哩哔哩_bilibili Parry_Skill.cs using UnityEngine; using UnityEngine.UI;public class P…

Python多态

1.多态 多态定义:多态(polymorphism)是指同一个方法调用由于对象不同可能会产生不同的行为 注意以下2点: 1.多态是方法的多态,属性没有多态。 2.多态的存在有2个必要条件:继承、方法重写 class Animal:de…

LearnOpenGl练习题-着色器

LearnOpenGl练习题-着色器 题目地址:着色器 - LearnOpenGL CN 题目一:修改顶点着色器让三角形上下颠倒: #version 330 core layout (location 0) in vec3 aPos; layout (location 1) in vec3 aColor; out vec3 ourColor; void main() {gl…

openEuler 22.03 LTS SP3源码编译部署OpenStack-Bobcat(Neutron使用OVN)

openEuler 22.03 LTS SP3部署OpenStack-Bobcat 说明机器详情安装操作系统注意事项基础准备Controller节点 && Compute节点 && Block节点关闭防火墙关闭selinux设置静态IP更新安装前准备Controller节点 && Compute节点 && Block节点设置主机名配…

简单认识Git(dirsearch、githack下载),git泄露(ctfhub)

目录 dirsearch下载地址: githack下载(一次不成功可多试几次) 一、什么是Git 1.git结构 2.git常用命令及示例 3.Git泄露原理 二、Git泄露 1.Log 2.Stash 3.Index 工具准备:dirsearch、githack dirsearch下载地址: GitHub - mauroso…

配置流策略实现不同网段间限制互访

在创建了 vlanif 接口并配置 IP 地址后,不同 vlan 间就可以互通了。 如果我们想要限制vlan 之间的通信,就可以通过配置流策略实现。 配置步骤(以华为交换机为例) 1、ACL 定义拒绝通过的数据流 2、定义流分类,按照ACL 对报文进行分类 3、配置流行为,动作为deny 4、配置流…

计算机不联网是否有IP地址

计算机不联网是否会有IP地址,这个问题涉及到计算机网络的基础知识。要深入探讨这个问题,我们需要从IP地址的定义、作用,以及计算机在不联网状态下的网络配置等多个方面进行分析。 首先,IP地址(Internet Protocol Addre…