InnoDB表空间
表空间就是存放页的地方。
类型名称 | 十六进制 | 描述 |
---|---|---|
FIL_PAGE_TYPE_ALLOCATED | 0x0000 | 最新分配,还没使用 |
FIL_PAGE_UNDO_LOG | 0x0002 | Undo日志页 |
FIL_PAGE_INODE | 0x0003 | 段信息节点 |
FIL_PAGE_IBUF_FREE_LIST | 0x0004 | Insert Buffer空闲列表 |
FIL_PAGE_IBUF_BITMAP | 0x0005 | Insert Buffer位图 |
FIL_PAGE_TYPE_SYS | 0x0006 | 系统页 |
FIL_PAGE_TYPE_TRX_SYS | 0x0007 | 事务系统数据 |
FIL_PAGE_TYPE_FSP_HDR | 0x0008 | 表空间头部信息 |
FIL_PAGE_TYPE_XDES | 0x0009 | 扩展描述页 |
FIL_PAGE_TYPE_BLOB | 0x000A | BLOB页 |
FIL_PAGE_INDEX | 0x45BF | 索引页,也就是我们所说的数据页 |
页面通用部分
File Header的组成部分
名称 | 占用空间大小 | 描述 |
---|---|---|
FIL_PAGE_SPACE_OR_CHKSUM | 4字节 | 页的校验和(checksum值) |
FIL_PAGE_OFFSET | 4字节 | 页号 |
FIL_PAGE_PREV | 4字节 | 上一个页的页号 |
FIL_PAGE_NEXT | 4字节 | 下一个页的页号 |
FIL_PAGE_LSN | 8字节 | 页面被最后修改时对应的日志序列位置(英文名是:Log Sequence Number) |
FIL_PAGE_TYPE | 2字节 | 该页的类型 |
FIL_PAGE_FILE_FLUSH_LSN | 8字节 | 仅在系统表空间的一个页中定义,代表文件至少被刷新到了对应的LSN值 |
FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID | 4字节 | 页属于哪个表空间 |
独立表空间结构
区的概念
64个页就是一个区,也就是64*16KB=1MB空间大小。
每256个区被划分成一组。
B+树中的同一层中的页是按照双向链表连接的,同一页中的记录是根据链表进行连接的。如果双向链表中相邻的两个页的物理位置不连续,对于传统机械硬盘来说,需要重新定位磁头位置,会产生随机I/O。所以尽量需要使页连续,所以引入区。而区中的页在物理上都是连续的。
第一个组的前三个页面都是固定的。
FSP_HDR:用来登记整个表空间的一些整体属性以及本组所有的区的属性。
IBUF_BITMAP:用来存储Change Buffer的一些信息。
INODE:用来存储INODE Entry。
其余各组开始的两个页面也固定。
XDES:用来登记本组256个区的属性。
段的概念
叶子节点和非叶子节点都有各自的区。存放叶子节点的区的集合是一个段,存放非叶子节点的区的集合也是一个段。
有一个直属于表空间的碎片区存放不同用处的页。
为某个段分配存储空间的策略:
- 刚开始向表中插入数据,段从某个碎片区以单个页面为单位来分配存储空间。
- 当某个段已经占用了32个碎片区页面之后,就以完整的区为单位来分配存储空间。
所以段是某些零碎的页面以及一些完整区的集合。
区的分类
状态名 | 中文名称 | 含义 |
---|---|---|
FREE | 空闲区 | 还没用到区中任何页面 |
FREE_FRAG | 有剩余空闲页面的碎片区 | 碎片区中还有页面可以分配 |
FULL_FRAG | 没有剩余空闲页面的碎片区 | 碎片区中没有页面可以分配 |
FSEG | 附属于某个段的区 | 区中页面完全用于存储某个段的数据 |
每一个区都对应一个XDES。
- Segment:段的唯一的编号
- List Node:将XDES串联成一个链表
- State:表明区的状态
- Page State Bitmap:每两位对应一个区中的页,第一位表示是否空闲,第二位没用到
申请页面过程:先查看是否有FREE_FRAG区,若存在,则从该区中取零碎页。若不存在,则申请一个FREE区变为FREE_FRAG区,然后取零碎页插入数据。若该区页面被取完,则变成FULL_FRAG区。
所以我们需要知道FREE,FREE_FRAG,FULL_FRAG这种区的情况,因此通过list Node将这三种情况的区的XDES结构各自串成链表。想要拿这三种情况的区时,就直接从链表中拿出来,并修改state的状态。
- FREE链表:链表中都是同一个段中所有页面都是空闲页面的区对应的XDES Entry结构
- NOT_FULL链表:链表中都是同一个段中所有页面仍有空闲页面的区对应的XDES Entry结构
- FULL链表:链表中都是同一个段中所有页面没有空闲页面的区对应的XDES Entry结构
用来定位链表。
- List Length:表示链表中节点个数
- First Node Page Number和First Node Offset表示该链表头结点在表空间的位置
- Last Node Page Number和Last Node Offset表示该链表尾结点在表空间的位置
段结构
- Segment ID:INODE Entry对应段的编号
- NOT_FULL_N_USED:在NOT_FULL链表已经使用了多少个页面
- 3个List Base Node
- Magic Number:标记INODE Entry是否已经被初始化,如果是97937874,即被初始化
- Fragment Array Entry:对应一个零散的页面,表示零散页面的页号
各类型页面
FSP_HDR类型
名称 | 中文名 | 占用空间大小(字节) | 简单描述 |
---|---|---|---|
File Header | 文件头部 | 38 | 页的一些通用信息 |
File Space Header | 表空间头部 | 112 | 表空间的一些整体属性信息 |
XDES Entry | 区描述信息 | 10240 | 存储本组256个区对应的属性信息 |
Empty Space | 尚未使用空间 | 5986 | 用于页结构的填充 |
File Trailer | 文件尾部 | 8 | 校验页是否完整 |
名称 | 占用空间大小(字节) | 描述 |
---|---|---|
Space ID | 4 | 表空间的ID |
Not Used | 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_FRAG链表的基节点 |
List Base Node for FULL_FRAG List | 16 | FULL_FRAG链表的基节点 |
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链表基节点 |
XDES类型
与FSP_HDR类型相似,但是该类型只记录本组的所有的区对应的XDES Entry。
IBUF_BITMAP类型
记录了一些关于Change Buffer的东西。
在修改非唯一二级索引页面时,如果该页面尚未被加载到 内存中,那么该修改将先被暂时缓存到Change Buffer中,之后服务器空闲或者其他什么原因导致对应的 页面从磁盘上加载到内存中时,再将修改合并到对应页面。
INODE类型
为了记录段的属性。
名称 | 中文名 | 占用空间大小(字节) | 简单描述 |
---|---|---|---|
File Header | 文件头部 | 38 | 页的一些通用信息 |
List Node for INODE Page List | 通用链表节点 | 12 | 存储上一个INODE页面和下一个INODE页面的指针 |
INODE Entry | 段描述信息 | 16320 | 具体的INODE Entry结构 |
Empty Space | 尚未使用空间 | 6 | 用于页结构的填充 |
File Trailer | 文件尾部 | 8 | 校验页是否完整 |
如果一个表空间中存在的段超过85个,那么一个INODE类型的页面不足以存储所有的段对应的INODE Entry结构,所以就需要额外的INODE类型的页面来存储这些结构。所以就将页面串成两个链表。
- SEG_INODES_FULL链表:没有空闲空间来存储额外的INODE Entry结构。
- SEG_INODES_FREE链表:还有空闲空间来存储额外的INODE Entry结构。
Segment Header结构
名称 | 占用空间大小(字节) | 描述 |
---|---|---|
Space ID of the 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 Header中存储的PAGE_BTR_SEG_LEAF记录着叶子节点段对应的INODE Entry结构的地址是哪个表空间中哪个页面的哪个偏移量。
PAGE_BTR_SEG_TOP记录着非叶子节点段对应的INODE Entry结构的地址是哪个表空间中哪个页面的哪个偏移量。
表空间大小
表空间是自扩展的。
系统表空间
系统表空间的ID为0。
页号 | 页面类型 | 英文描述 | 描述 |
---|---|---|---|
3 | SYS | Insert Buffer Header | 存储Change Buffer的头部信息 |
4 | INDEX | Insert Buffer Root | 存储Change Buffer的根页面 |
5 | TRX_SYS | Transction System | 事务系统的相关信息 |
6 | SYS | First Rollback Segment | 第一个回滚段的信息 |
7 | SYS | Data Dictionary Header | 数据字典头部信息 |
页号64~191的页面叫Doublewrite Buffer。
数据字典
表名 | 描述 |
---|---|
SYS_TABLES | 整个InnoDB存储引擎中所有表的信息 |
SYS_COLUMNS | 整个InnoDB存储引擎中所有列的信息 |
SYS_INDEXES | 整个InnoDB存储引擎中所有索引的信息 |
SYS_FIELDS | 整个InnoDB存储引擎中所有索引对应的列的信息 |
SYS_FOREIGN | 整个InnoDB存储引擎中所有外键的信息 |
SYS_FOREIGN_COLS | 整个InnoDB存储引擎中所有外键对应的列的信息 |
SYS_TABLESPACES | 整个InnoDB存储引擎中所有的表空间信息 |
SYS_DAATAAFILES | 整个InnoDB存储引擎中所有表空间对应的文件系统的文件路径信息 |
SYS_VIRTUAL | 整个InnoDB存储引擎中所有虚拟生成的列的信息 |
页号7的页
名称 | 占用空间大小(字节) | 简单描述 |
---|---|---|
File Header(文件头部) | 38 | 页的一些通用信息 |
Data Dictionary Header(数据字典头部) | 52 | 记录一些基本系统表的根页面位置以及InnoDB存储的一些全局信息 |
Unused | 4 | 未使用 |
Segment Header(段头部) | 10 | 记录本页面所在段对应的INODE Entry位置信息 |
Empty Space(尚未使用的空间) | 16272 | 用于业结构的填充 |
File Trailer | 8 | 校验页是否完整 |