首页 > 数据库 >MySQL学习(5)记录存在那里——表空间

MySQL学习(5)记录存在那里——表空间

时间:2023-10-13 23:33:07浏览次数:36  
标签:链表 记录 List FREE 学习 XDES MySQL Entry INODE

前言

存储引擎都是把数据存储在文件系统上,通过通过查询命令,可以查看数据目录所在的本机路径。

mysql> SHOW VARIABLES LIKE 'datadir';
+---------------+-----------------+
| Variable_name | Value           |
+---------------+-----------------+
| datadir       | /var/lib/mysql/ |
+---------------+-----------------+
1 row in set (0.00 sec)

每个数据库都在数据目录下有一个同名子目录,这是在新建数据库时,MySQL自动创建的。在数据库名对应的子目录下,每一张数据表都有一个同名以后缀名为.frm的文件,这个文件存储了表结构的定义。在InnoDB存储引擎中,表的数据存储在一个叫表空间的地方。

InnoDB页和表的关系

我们知道记录是保存在索引页中的,InnoDB为了管理这些页,提出了表空间的概念。本质上就是磁盘上的一个或多个文件。每一个表空间可以被划分成很多页。

根据表空间的类型可以划分为如下:

  1. 系统表空间

InnoDB在数据目录创建的名为ibdata1的文件,这个文件可以自己扩展大小。一个MySQL进程只有一个系统表空间,其中记录了一些与整个系统相关的信息。

  1. 独立表空间

在数据库同名的子目录中,每一张数据表都有一个同名以后缀名为.ibd的文件。它与.frm文件共同分别存储了表的结构和记录。

独立表空间结构

什么是区(extent)

表空间中连续的64个页就是一个区,也就是一个区默认占用1MB空间。无论是系统表空间还是独立表空间,都可以看成是若干个连续的区组成,每256个区为一组。

如下extent0-extent255位一组,extent256-extent511位一组,以此类推。

每个组头几个页

第一组前面3个页始终是这三种页:

  • FSP_HDR:用于记录表空间的一些属性以及本组所有区的XDES Entry数据结构,也就是有256个。

  • IBUF_BITMAP:存储Change Buffer的一些信息。

  • INODE:存储了若干INODE Entry数据结构。

其余组前2个页始终是这两种:

  • XDES:存储本组所有区的XDES Entry数据结构。

  • IBUF_BITMAP:同上。

什么是段(segment)

同一个索引的B+树结构中,目录项所在的页,也就是非叶子节点所在的区的集合为一个段,叶子节点所在的区的集合为一个段。一个索引会生成两个段,一个叶子节点段和一个非叶子节点段。

表中数据较少时,每次新插入一条记录,都会被插入到一个碎片区中,当使用了32个碎片区中的页后,会分配一个完整的区,原先碎片区中的页不会被复制到新的完整的区中。因此段是某些零散页面以及一些完整的区的集合

什么是碎片区(fragment)

碎片区也是由64个页组成,只属于表空间。结构上和其他的区没有啥不同。碎片区中的页用于不同目的,不限制于某个索引的某个段。有些页属于段A,有些页属于段B。

区的分类

4种类型:

  • 空闲的区(FREE)

  • 有剩余空闲页面的碎片区(FREE_FRAG)

  • 没有剩余空闲页面的碎片区(FULL_FRAG)

  • 属于某个段段区(FSEG)

其中FREE、FREE_FRAG和FULL_FRAG独立且直属于表空间;FSEG属于某个段。

什么是XDES Entry

XDES Entry是一种用于更好管理区的数据结构,每个区都对应一个XDES Entry结构,这个结构存放在每个组都FSP_HDR或XDES页中。

XDES Entry结构示意图

每个XDES Entry由40个字节构成,分为4个部分。

  • Segment ID表示所属段的编号,若不属于任何段,这个属性无意义。

  • List Node包含前一个XDES Entry和后一个XDES Entry的指针,通过这些指针可以构成双向链表结构。

  • State的值表示这个区的状态,也就是FREE、FREE_FRAG、FULL_FRAG或FSEG。

  • Page State Bitmap共16个字节,合128比特位,没两个比特位代表一个页。其中第1位表示对应的页是否空闲。

什么是XDES Entry链表

利用XDES Entry中的List Node,将相同类型的区串成双向链表,这么做的好处是减少随机I/O,又不至于让数据少的表浪费空间,避免每次想找到一种类型的区时要遍历所有的区。

  • FREE链表,包含不属于任何段,且所有页面都是空闲页面的区

  • FREE_FRAG链表,包含不属于任何段,且有剩余空闲页面的区

  • FULL_FRAG链表,包含不属于任何段,且没有剩余空闲页面的区

属于某个段的区中会根据List Node串成三种链表:

  • FREE链表,包含同一个段中,所有页main都是空闲页面的区

  • NOT_NULL链表,包含同一个段中,存在空闲页面的区

  • FULL链表,包含同一个段中,已经没有空闲页面的区

插入记录流程如下所示:

InnoDB表空间插入记录流程图

每一个链表的头节点和尾节点以及这个链表中包含了多少个节点的信息被记录在一个叫List Base Node链表基节点的结构中,占用16个字节。

碎片区中的链表基节点存放在FSP_HDR页中的File Space Header中,附属于段的链表基节点存放在INODE Entry结构中。

什么是INODE Entry

段不同于区,它是一个逻辑概念,由若干个零散页面和一些完整的区组成。与XDES Entry类似,每一个段有一个INODE Entry结构,存放在表空间第一组的INODE页。

INODE Entry结构如下:

INODE Entry结构示意图

  • Segment ID:段编号

  • NOT_FULL_N_USED:NOT_FULL链表中已经使用了页面数量

  • List Base Node For FREE List:FREE链表的基节点。

  • List Base Node For NOTE_FULL List:NOT_FULL链表的基节点。

  • List Base Node For FULL List:FULL链表的基节点。

  • Magic Number:用来标记这个INODE Entry是否已经被初始化,也就是把各个字段的信息都填上了。该值为97937874,表明该INODE Entry已被初始化,否则没有被初始化。

  • Fragment Array Entry:32个,对应着属于该段的零散页面的页号。

直属于表空间的区,每个区对应一个XDES Entry,根据区的状态分别建立3个链表,链表基节点存放在FSD_HDR页。附属于段段区,根据页面空闲状态,分别建立3个链表,链表基节点存放在INODE Entry。

什么是FSP_HDR页

一个表空间只有一个FSP_HDR页,其结构如下:

FSP_HDR页结构示意图

File Header、File Trailer与其他类型的页类似,主要关注File Space Header和XDES Entry。

  1. File Space Header部分

File Space Header结构如下:

FIle Space Header结构示意图

  • Space ID字段表示表空间编号。

  • Size字段表示当前表空间拥有的页面数。

  • FREE Limit字段表示未被初始化的最小页号。空间增大时,不会立即将空闲空间加入到FREE链表,只将一部分加入到FREE链表,等FREE链表中的XDES Entry对应的区不够用时,再把没有加入FREE链表的区对应的XDES Entry加入到FREE链表,FREE Limit表示还未加入到FREE链表的最小页号。

  • Space Flags表示表空间中的一些状态属性。

  • FRAG_N_USED字段表示FREE_FRAG链表中已经使用的页面数量。

  • List Base Node for FREE List、List Base Node for FREE_FRAG List、List Base Node for FULL_FRAG List着3个字段分别表示FREE链表、FREE_FRAG链表和FULL_FRAG链表的基节点。使得定位链表更容易。

  • NEXT Unused Segment ID字段表示下一个新建段的ID,类似于自增主键。

  • List Base Node for SEG_INODES_FULL字段表示SEG_INODES_FULL链表的基节点。

  • List Base Node for SEG_INDOES_FREE字段表示SEG_INODES_FREE链表的基节点。

  1. XDES Entry部分

每个区对应一个XDES Entry结构,一个XDES Entry占用40个字节,一个组有256个组,表空间第一组中的所有区对应的XDES Entry就存储在FSP_HDR页的XDES Entry部分中。

什么是XDES页

XDES页和FSP_HDR页结构相似,区别在于XDES页没有了FIle Space Header部分。功能就是存储本组中所有区对应的256个XDES Entry。

什么是IBUF_BITMAP页

每个组第二个页都是IBUF_BITMAP,这种类型的页记录了有关Change Buffer的东西。

Change Buffer本质是表空间中的一颗B+树,它的根节点存储在系统表空间中。在修改非唯一二级索引页面时,如果该页尚未被加载到内存,那么该修改将被暂时缓存在Change Buffer中,之后服务器空闲或加载了该页到内存中,再将修改和冰岛该页面。

什么是INODE页

第一个分组中第三个页面的类型是INODE,其结构如下:

INODE页结构示意图

List Node for INODE Page List为前一个INODE页和后一个INODE页的指针,每个段对应的INODE Entry结构会急中存放在INODE页中,每个INODE Entry占用192字节,一个INODE页可以存放85个INODE Entry结构。如果表中索引特别多,每个索引对应两个段,所以一个INODE页不够用,就会使用多个INODE页来进行存储。这些INODE页会形成两个链表。

  • SEG_INODES_FULL链表:已经没有空闲空间用来存储INODE Entry的INODE页所建立的链表。

  • SEG_INODES_FREE链表:还有剩余空间用来存储INODE Entry的INODE页所建立的链表。

什么是Segment Header

为了知道某个段对应哪个INODE Entry结构,在段中的记录所在的页,也就是INDEX页Page Header部分有这样两个属性:

名称大小描述
PAGE_BTR_SEG_LEAF 10字节 B+树叶子节点段段头部信息,仅在B+树段根页中定义
PAGE_BTR_SEG_TOP 10字节 B+树非叶子节点段的头部信息,仅在B+树的根页中定义

这10个字节对应的是一个Segment Header结构:

名称大小描述
Space ID for INODE Entry 4字节 INODE Entry结构所在的表空间ID
Page Number of the INODE Entry 4字节 INODE Entry结构所在的页面页号
Byte Offset of the INODE Entry 2字节 INODE Entry结构在该页中偏移量

这样,PAGE_BTR_SEG_LEAF记录着叶子节点段对应的INODE Entry结构的地址,PAGE_BTR_SEG_TOP记录着非叶子节点对应的INODE Entry结构的地址。一个索引值对应两个段,所在只需要在索引的根页面记录这两个结构即可。

 

阅读学习自《MySQL是怎样运行的》小孩子4919

标签:链表,记录,List,FREE,学习,XDES,MySQL,Entry,INODE
From: https://www.cnblogs.com/haleyeung/p/17763531.html

相关文章

  • 将excel文件导入到Navicat的mysql中步骤详解
    将转换好的csv文件导入到Navicat中1、右键数据库中表的名称,选中导入向导:2、之后选择导入的文件结构:我们在这里选中excel类型;点击下一步;3、浏览到excel文件的路径然后选中该表:点击下一步;4、自定义一些附加选项点击下一步;5、选中这个新建表然后点击下一步;6、修改表......
  • 萌新学习c语言记录
    今天写的题要求使用while语句发现输出一直循环一直循环着最后一个数然后看别人的答案发现要这样做然后我搜索了一下发现while(scanf("%d",&a)!=EOF)可以检查输入是否成功如果不输入的话将不会进行下一步......
  • 学习C语言心得-自定义函数 输入两个数字求和
    输入两个数字求和#include<stdio.h>intsum(inta,intb){ returna+b;}intmain(){ inta=0; intb=0; printf("请输入ab的值:"); scanf("%d%d",&a,&b); intSum=sum(a,b); printf("Sum=%d",Sum); return0;}运行......
  • 学习C语言心得-传址调用
    运用传址调用来交换两个数#include<stdio.h>inttransform(int*a,int*b){ intx=0; x=*a; *a=*b; *b=x;}intmain(){ inta=10; intb=20; printf("交换前:%d%d\n",a,b); transform(&a,&b); printf("交换后:%d%d\n",......
  • 学习C语言心得-运用自定义函数求素数
    自定义函数求素数#include<stdio.h>intpanduan(inta){ inti=0; for(i=2;i<a;i++) { if(a%i==0) { returna; } } return0;}intmain(){ intnumber=0; printf("请输入一个数:"); scanf("%d",&number); int......
  • Huawei模拟器的一些问题记录
    1.每次更改配置弹出的命令,使用该命令进行屏蔽。2.进入系统模式system-view命令:<Huawei>--->[Huawei]3.ctrl+z后退出后才能进行save命令4.展示命令:displayportvlandisplayvlan......
  • MySQL删除表的命令是什么
    MySQL删除表命令:删除表命令是DROPTABLE,其基本语法如下:删除单个表DROPTABLEtable_name;注:这个命令会直接删除指定表,如果这个表不存在就会报错。另外,删除表之前最好做好备份。同时删除多个表DROPTABLEtable_name1,table_name2,...;注:这个命令可以同时删除多张......
  • 文件默认打开方式 + mysql导入错误 + 输入法问题
    文件默认打开方式默认应用修改:设置—》应用—》默认应用—》按文件类型指定默认应用mysql导入错误Unknowncollation:'utf8mb4_0900_ai_ci'Mysql导入sql文件时,出Unknowncollation:'utf8mb4_0900_ai_ci'错误。原因:sql文件是从高版本mysql(8.0)中导出的,导入到......
  • mysql数据库性能优化
    数据库的性能优化可以从以下几个方面进行优化:1.硬件和操作系统:硬件可以从cpu、内存、I/O,网络带宽等方面进行优化。系统层可以从文件句柄数,网络配置等方面2.数据库的架构:比如主从集群以及主从架构的变种可以做高可用及容灾,读写分离可以避免读操作比较高的服务影响数据写入,分库分表......
  • 8088/8086微处理器与总线学习笔记总结
    目录一、微处理器与总线1.微处理器的概述1.1运算器1.2控制器1.2.1指令控制1.2.2时序控制1.2.3操作控制二、8086/8088微处理器1.8086/8088CPU的指令特点1.1指令流水线1.2内存的分段管理技术1.3支持多处理器系统2.8088/8086的外部引脚及其功能3.8086/8088的功能结构3.1内部......