页面通用部分
数据页,也就是INDEX类型的页由7个部分组成
- File Header:记录页面的一些通用信息
- File Trailer:校验页是否完整,保证从内存到磁盘刷新时内容的一致性。
独立表空间结构
区(extent)的概念
设计InnoDB的大叔们提出了区(英文名:extent)的概念。对于16KB的页来说,连续的64个页就是一个区,也就是说一个区默认占用1MB空间大小。不论是系统表空间还是独立表空间,都可以看成是由若干个区组成的,每256个区被划分成一组。画个图表示就是这样:
从上图中我们能得到如下信息:
- 第一个组最开始的3个页面的类型是固定的,也就是说extent 0这个区最开始的3个页面的类型是固定的,分别是:
- FSP_HDR类型:这个类型的页面是用来登记整个表空间的一些整体属性以及本组所有的区,也就是extent 0 ~ extent 255这256个区的属性,稍后详细唠叨。需要注意的一点是,整个表空间只有一个FSP_HDR类型的页面。
- IBUF_BITMAP类型:这个类型的页面是存储本组所有的区的所有页面关于INSERT BUFFER的信息。
- INODE类型:这个类型的页面存储了许多称为INODE的数据结构。
其余各组最开始的2个页面的类型是固定的,也就是说extent 256、extent 512这些区最开始的2个页面的类型是固定的,分别是:
-
XDES类型:全称是extent descriptor,用来登记本组256个区的属性,也就是说对于在extent 256区中的该类型页面存储的就是extent 256 ~ extent 511这些区的属性,对于在extent 512区中的该类型页面存储的就是extent 512 ~ extent 767这些区的属性。上边介绍的FSP_HDR类型的页面其实和XDES类型的页面的作用类似,只不过FSP_HDR类型的页面还会额外存储一些表空间的属性。
-
BUF_BITMAP类型:上边介绍过了。
段(segment)的概念
某个段分配存储空间的策略是这样的:
- 在刚开始向表中插入数据的时候,段是从某个碎片区以单个页面为单位来分配存储空间的。
- 当某个段已经占用了32个碎片区页面之后,就会以完整的区为单位来分配存储空间。
段是某些零散的页面以及一些完整的区的集合。
- 除了索引的叶子节点段和非叶子节点段之外,InnoDB中还有为存储一些特殊的数据而定义的段,比如回滚段,当然我们现在并不关心别的类型的段,现在只需要知道段是一些零散的页面以及一些完整的区的集合就好了。
- 默认情况下一个使用InnoDB存储引擎的表只有一个聚簇索引,一个索引会生成2个段
区的分类
状态名 | 含义 |
---|---|
FREE | 空闲的区 |
FREE_FRAG | 有剩余空间的碎片区 |
FULL_FRAG | 没有剩余空间的碎片区 |
FSEG | 附属于某个段的区 |
处于FREE、FREE_FRAG以及FULL_FRAG这三种状态的区都是独立的,算是直属于表空间;而处于FSEG状态的区是附属于某个段的。
为了方便管理这些区,设计InnoDB的大叔设计了一个称为XDES Entry的结构(全称就是Extent Descriptor Entry),每一个区都对应着一个XDES Entry结构,这个结构记录了对应的区的一些属性。我们先看图来对这个结构有个大致的了解:
XDES Entry是一个40个字节的结构,大致分为4个部分
- Segment ID(8字节)
每一个段都有一个唯一的编号,用ID表示,此处的Segment ID字段表示就是该区所在的段。 - List Node(12字节)
这个部分可以将若干个XDES Entry结构串联成一个链表,大家看一下这个List Node的结构:
- State(4字节)
这个字段表明区的状态。可选的值就是我们前边说过的那4个,分别是:FREE、FREE_FRAG、FULL_FRAG和FSEG。 - Page State Bitmap(16字节)
我们说一个区默认有64个页,这128个比特位被划分为64个部分,每个部分2个比特位,对应区中的一个页。比如Page State Bitmap部分的第1和第2个比特位对应着区中的第1个页面,第3和第4个比特位对应着区中的第2个页面。