10.表空间结构
独立表空间:
- 表空间的是由
若干个区
组成的 区(extent)
:连续的64个页
就是一个区extent
,默认占用1MB空间大小。为什么要有区
:同层的索引页之间以链表组织,物理距离可能会比较远,这样就会引起随机IO
。使用区可以保证64个页的连续)
段(segment)
:- 定义:某些
零散的页
以及一些完整的区
的集合 - innodb段分类:
- 索引段:存放 B + 树的非叶子节点的区的集合;
- 数据段:存放 B + 树的叶子节点的区的集合;
- 回滚段:存放的是回滚数据的区的集合
- 定义:某些
碎片区(fragment)
:- 背景:以完整的区为单位分配给某个段,对于数据量较小的表太浪费存储空间
- 在一个碎片区中的页可以给不同的段分配页
区(extent)示意图:

FSP_HDR 类型页(特殊的XDES类型页):
第一个组的第一个页,当然也是表空间的第一个页,页号为0
。这个页的类型是FSP_HDR
,它存储了表空间的整体属性以及第一个组内256个区的对应的XDES Entry
结构
File Space Header:

File Space Header结构 | 空间大小 | 描述 |
---|---|---|
Space ID | 4字节 | 表空间的ID |
Not Used | 4字节 | 这4个字节未被使用,可以忽略 |
Size | 4字节 | 当前表空间占有的页数 |
FREE Limit | 4字节 | 尚未被初始化的最小页号,大于或等于这个页号的区对应的XDES Entry结构都没有被加入FREE链表 |
Space Flags | 4字节 | 表空间的一些占用存储空间比较小的属性 |
FRAG_N_USED | 4字节 | FREE_FRAG链表中已使用的页数量 |
List Base Node for FREE List | 16字节 | FREE链表的基节点 |
List Base Node for FREE_FRAG List | 16字节 | FREE_FREG链表的基节点 |
List Base Node for FULL_FRAG List | 16字节 | FULL_FREG链表的基节点 |
Next Unused Segment ID | 8字节 | 当前表空间中下一个未使用的 Segment ID |
List Base Node for SEG_INODES_FULL List | 16字节 | SEG_INODES_FULL链表的基节点 |
List Base Node for SEG_INODES_FREE List | 16字节 | SEG_INODES_FREE链表的基节点 |
记录插入时的区的分配:
当段中数据较少的时候,首先会查看表空间中是否有状态为FREE_FRAG
的区,也就是找还有空闲空间的碎片区;如果找到了,那么从该区中取一些零碎的页把数据插进去;否则到表空间下申请一个状态为FREE
的区,也就是空闲的区,把该区的状态变为FREE_FRAG
,然后从该新申请的区中取一些零碎的页把数据插进去。之后不同的段使用零碎页的时候都会从该区中取,直到该区中没有空闲空间,然后该区的状态就变成了FULL_FRAG
*
把状态为FREE
的区对应的XDES Entry
结构通过List Node
来连接成一个链表,这个链表我们就称之为FREE
链表。
*
把状态为FREE_FRAG
的区对应的XDES Entry
结构通过List Node
来连接成一个链表,这个链表我们就称之为FREE_FRAG
链表。
*
把状态为FULL_FRAG
的区对应的XDES Entry
结构通过List Node
来连接成一个链表,这个链表我们就称之为FULL_FRAG
链表。
这样每当我们想找一个FREE_FRAG
状态的区时,就直接把FREE_FRAG
链表的头节点拿出来,从这个节点中取一些零碎的页来插入数据,当这个节点对应的区用完时,就修改一下这个节点的State
字段的值,然后从FREE_FRAG
链表中移到FULL_FRAG
链表中。同理,如果FREE_FRAG
链表中一个节点都没有,那么就直接从FREE
链表中取一个节点移动到FREE_FRAG
链表的状态,并修改该节点的STATE
字段值为FREE_FRAG
,然后从这个节点对应的区中获取零碎的页就好了
XDES Entry:用来记录区的属性

IBUF_BITMAP 类型页:
记录了一些有关Change Buffer
INODE 类型页:
每个索引定义了两个段,而且为某些特殊功能定义了些特殊的段。为了方便管理,又为每个段设计了一个INODE Entry
结构,这个结构中记录了关于这个段的相关属性
。
段其实不对应表空间中某一个连续的物理区域,而是一个逻辑上的概念,由若干个零散的页以及一些完整的区组成。
INODE Entry(段结构):用来记录段的属性
为每个段中的区对应的
XDES Entry
结构建立了三个链表
: *
FREE
链表:同一个段中,所有页都是空闲的区对应的XDES Entry
结构会被加入到这个链表。注意和直属于表空间的FREE
链表区别开了,此处的FREE
链表是附属于某个段的。
*
NOT_FULL
链表:同一个段中,仍有空闲空间的区对应的XDES Entry
结构会被加入到这个链表。
*
FULL
链表:同一个段中,已经没有空闲空间的区对应的XDES Entry
结构会被加入到这个链表。
XDES 类型页:
每个XDES Entry
结构对应表空间的一个区。在区的数量非常多时,一个单独的页可能就不够存放足够多的XDES Entry
结构,所以我们把表空间的每256个区,分为了若干个组。每组开头的一个页记录着本组内所有的区对应的XDES Entry
结构。由于第一个组的第一个页(FSP_HDR
)有些特殊,因为它也是整个表空间的第一个页,所以除了记录本组中的所有区对应的XDES Entry
结构以外,还记录着表空间的一些整体属性。整个表空间里只有一个这个类型的页。
区的状态(State):
状态名 | 含义 | 从属 |
---|---|---|
FREE | 空闲的区 | 直属于表空间 |
FREE_FRAG | 有剩余空间的碎片区 | 直属于表空间 |
FULL_FRAG | 没有剩余空间的碎片区 | 直属于表空间 |
FSEG | 附属于某个段的区 | 附属于某个段 |
汇总:

本文作者:navyum
本文链接:https://www.cnblogs.com/navyum/p/18509404
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步