4、InnoDB表空间
2021-10-27 16:20:38 0 举报
InnoDB独立表空间整体结构。如有错误的地方欢迎各位指点迷津
作者其他创作
大纲/内容
extent 513
段结构 INODE Entry
XDES
First Node Offset 2字节
...
对于一个页来说,它分很多种类型,并不只是单单用于存储索引,还有其他的类型都可以用页来存储。那么在这些不同类型的页当中就有他们公用的部分
List Node 12字节
在NOT_FULL链表中已经使用了多少个页
FRAG_N_USED 4字节
List Base Node For NOT_FULL List 16字节
Next Node Offset 2字节
...
List Base Node For FULL List 16字节
Empty Space 5986字节
一样
File Trailer 8字节
extent 257
指向前一个XDES Entry的指针
Fragment Array Entry0 4字节
相似,没有File Space Header部分
第二组开始每组第一个区的页
State:FREE、FREE_FRAG、FULL_FRAG
某个段中区的链表
FREE
Fragment Array Entry1 4字节
标记当前INODE是否被初始化,值是97937874表示已经初始化,没特殊含义
4、碎片区(fragment):在一个碎片区中,并不是所有的页都是为了存储同一个段的数据而存在的,在碎片区中的页可以用于不同的目的,可能有些页存储了段1,另一个存储的就是段2。碎片区直属于表空间,不属于任何一个段碎片区是解决什么问题的?想一下,一个索引会生成2个段,而段是以区为单位申请存储空间的,一个区默认是1MB。如果我们只存了几条数据难道也需要申请2MB的内存吗?要知道我们每加一个索引就会多加两个段,这显然不能这样做。所以就引用了碎片区这个东东,在刚开始向表插入数据的时候,段从某个碎片区以单个页为单位来分配存储空间。当某个段已经有32个页在碎片区的时候,就会以完整个区为单位分配存储空间
IBUF_BITMAP
State 4字节
Prev Node Offset 2字节
extent 0
Segment ID 8字节
First Node Page Number 4字节
XDES Entry 0 40字节
每256个区为一组
File Header 38字节
extent 1
NOT_FULL
Next Node Page Number 4字节
表空间是一个抽象的概念,我们在mysql存储的数据最终会达到文件系统中(也就是磁盘),而帮助我们存储这些数据就是表空间。对于系统表空间来说,对应着文件系统中一个或多个实际文件;对于独立表空间来说,对应的文件系统中一个名为表名.ibd的实际文件。 这里不得不提一嘴mysql的数据目录,一般平常我们只接触过安装目录,也就是我们在安装mysql指定的,里面有非常重要的bin目录存储着很多非常重要的可执行文件。但是数据目录就不一样了,这两个完全是两码事。数据目录是用来存储mysql在运行过程中产生的数据,所以一定要区分开。我们可以用show variables like‘datadir’来查看对应的数据目录。而在数据目录的数据库目录下存放着我们专门用于描述表结构的文件——表名.frm。在独立表空间下还会在数据库的目录下创建一个——表名.ibd文件,用于表示独立表空间文件 而.ibd文件就是这次重点要谈的对象,回想一下,InnoDB是以页为单位去管理存储空间的,聚簇索引和其他的二级索引都是以B+树的形式保存到表空间中,而B+树的节点就是数据页,这个页的类型其实就是fil_page_index(索引页\\数据页)。
FULL
在说独立表空间结构之前需要先了解几个概念
Size 4字节
INODE
.......
很多
FREE_FRAG
Last Node Offset 2字节
List Base Node for SEG_INODE_FREE16字节
FREE、NOT_FULL、FULL链表基节点
INODE Entry0 192字节
extent 255
3、随机IO和顺序IO:当我们在查询一定范围数据的时候,只需要找到最左和最右的记录,然后按照双向链表去遍历就可以了。如果这时候两个链表中相邻页的物理位置离的非常远的话就是随机IO。而两个物理位置也是相邻的那就是顺序IO。随机IO是非常慢的,所有在InnoDB中就引入了区。一个区是一个在物理位置上连续的64个页
State:FSEG 按照每个段区分
List length4字节
指向XDES Entry链表尾节点指针
FREE Limit 4字节
Space ID 4字节
FULL_FRAG
List Base Node链表基节点
size:当前表空间占有的页数FREE Limit:没有被初始化的最小页号,大于等于这个页号没有加入FREE链表Space Flags:表空间的一些占有存储空间比较小的属性FRAG_N_USED:FREE_FRAG链表已使用页数量Next Unused Segment ID:表空间中未使用的下一个Segment ID(INODE Entry类型的页链表)List Base Node for SEG_INODES_FULL list:SEG_INODES_FULL基节点List Base Node for SEG_INODES_FREE list:SEG_INODES_FREE基节点
extent 256
NOT_FULL_N_USD 4字节
共有32个,存储的是一些零散的页,也就是碎片区存储的页
List Node for INODE Page List 12字节
File Trailer
直属于表空间碎片区链表
指向后一个XDES Entry的指针
File Header 38字节
File Space Header:存储表空间的一些属性信息XDES Entry:存储本组256个组对应的属性信息Empty Space:页结构填充
File Space Header 112字节
Page State Bitmap 16字节
XDES Entry组成的各种链表
5、区的分类:FREE:空闲的区 FREE_FRAG:有剩余空间的碎片区 FULL_FRAG:没有剩余空间的碎片区 FSEG:附属于某个段的区当处于区的state处于FSEG状态时,表示当前的区属于某个段的,处于其他三种状态时,表示当前的区直属于表空间
extent0的每个页
FSP_HDR
指向XDES Entry链表头节点指针
XDES:登记本组所有区的属性,与FSP_HDR相似
Segment ID:当前区所在段的段IDList Node:将若干个XDES Entry组成链表State:表示当前区的状态,也就是上面说的分类Page State Bitmap:16个字节也就是128个比特位。一个区有64页也就是说,第一个和第二个比特位对应的就是第一个页,以此类推
Last Node Page Number 4字节
Magic Number 4字节
2、段(segment):这里面存放了很多很多的区。每当创建一个索引,就会出现两个段,一个段是专门存放B+树叶子节点页的区的,另一个段是存放非叶子节点页的区的
List Base Node for FREE List 16字节
extent 512
FSP_HDR:用来登记整个表空间的一些整体属性以及本组所有的区IBUF_BITMAP:存储本组所有区的所有页关于insert buffer的信息。INODE:存储为INODE的数据结构(段结构)
XDES Entry 255
List Base Node for FREE_FRAG List16字节
Next Unused Segment ID 8字节
File Header
不同类型的页这里面的作用是不同的
List Base Node for FREE List16字节
Not Userd 4字节
存储着每个区对应的XDES Entry结构
Prev Node Page Number 4字节
List Base Node for FULL_FRAG List16字节
Fragment Array Entry31 4字节
List Base Node for SEG_INODES_FULL16字节
Empty Space 6字节
Space Flags 4字节
extent 511
1、区(extent):在表空间中存储的页实在太过了,为了更好的管理这些页,就提出了区这个概念。在16KB大小的情况下,连续的64个页是一个区,也就是一个区默认1MB空间大小。而这么多的区可以分为若干个组,每256个区划分为一个组
6、区组成的各种链表当state处于FREE、FREE_GRAG、FULL_FRAG的时候,表示当前区为碎片区,只属于表空间的。为了快速找到符合条件的区,将这些区分别组成一个链表。当一条数据过来的时候,先去FREE_FRAG头结点找到一个,如果没有去FREE头结点拿一个并移动到FREE_FRAG链表中,并改变状态,将数据的页放入这个区内。当这个区满的时候就给将状态变为FULL_FRAG并移动到FULL_FRAG链表中当state处于FSEG的时候,表示当前的区是属于某个段的。当数据很多的时候区的数量也会膨胀起来,而且这些区都属于不同的段,为了快速找到某个段中符合条件的区,就将同一个段(Segment ID)中的区分为了三个链表。当某个段中被添加一条数据的时候,会优先找NOT_FULL的头结点,如果没有就去FREE链表拿,并移动到NOT_FULL链表,然后插入数据,当这个区满的时候就会移动到FULL链表中他为什么要搞这么多的链表呢?试想一下,如果我们的数据非常之多,以至于区可能有上万、几十万之多,如果没有链表的维护,我们又该如何找到这个符合条件的区呢?难道一个一个去遍历?不,这太损耗性能了,InnoDB绝对不允许这样的!
0 条评论
下一页