页通用结构
在InnoDB数据页部分介绍了类型为FIL_PAGE_INDEX的索引页(数据页)的结构,参考如下链接:
除了数据页,其他类型的页枚举值如下:
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|索引页
这些不同的页,它们的共同结构都是38字节的File Header + 8字节的File Trailer + 16338字节的其他内容
其中File Header之前也看过:
而File Trailer用于校验页的完整性的,包括8个字节的固定空间,防止写数据时写了一半停机,回来可以判定这个页是否是完整的
独立表空间结构
区(extent)和组
在InnoDB的文件系统中,一个库就是一个.ibd文件,里面存放的是数据页
一个页16KB,为了管理页,让64个页为1个区extent,因此一个区占1MB;而256个区为一组,即一组有256MB
每个组的第一个区中也是有固定内容的,也就是固定类型的页,其中
组1的extent0中包含一个FIL_PAGE_TYPE_FSP_HDR 、一个FIL_PAGE_IBUF_BITMAP 、一个FIL_PAGE_INODE
而后续组中的第一个区extent都是固定包含一个FIL_PAGE_TYPE_XDES 、一个FIL_PAGE_IBUF_BITMAP
FIL_PAGE_TYPE_FSP_HDR:用来记录整个表空间(.ibd)文件的整体属性,以及本组所有的区,一个表空间中只有一个该类型的页
FIL_PAGE_IBUF_BITMAP:记录该区所有页面的INSERT BUFFER信息
FIL_PAGE_INODE:存储INODE结构
FIL_PAGE_TYPE_XDES:登记本组中256个区的属性
段segment
段的出现是为了解决查询时随机I/O的问题
如果MySQL的内存空间是完全不连续的,基于B+树查找到一批数据时,需要逐个跳到对应的地址取数,这样就是随机I/O,这样性能是很差的
所以尽量让B+树相邻的节点页的物理地址也相邻,这样可以顺序读取内存,即顺序I/O,性能就好一些
也就是说,引入区的概念,即让64个页具有连续的物理地址
同时,B+树叶子节点里面存放的是真实记录或真实索引列,非叶子节点存的全是目录,如果把叶子节点和非叶子节点分别放到不同的区里面,性能就更好了,因此就有了段的概念,即一个树维护两个段,每个段至少一个区,即一个树2MB的空间
那么具有1个二级索引的表,默认维护两棵树,四个段,至少4MB空间
但是如果维护一个树就要申请2MB,这样申请空间又过于浪费了,因此InnoDB又提出了一个碎片区的概念,这个区中的页,有些归属于段A,有些归属于段B,有些甚至不属于任何段,且碎片区直属于表空间,这样:
在刚开始向表中插入数据时,段是从某个碎片区以单个页面为单位分配存储空间
当一个段已经占用了32个碎片区中的页,就会以完整的区为单位分配空间
区的分类
根据前面段的介绍,可以得到区的状态概念:
FREE:空闲区
FREE_FRAG:有剩余空间的碎片区
FULL_FRAG:没有剩余空间的碎片区
FSEG:附属于某个段的区
其中FREE、FREE_FRAG、FULL_FRAG都是独立状态,直属于表空间,而FSEG则是附属于某个段
XDES链表
为了管理一堆区,InnoDB涉及了一个XDES Entry结构,其中存放的是区所属的段ID、一个ListNode链表指向前/后一个XDES Entry,另外就存放区的状态(空闲还是有剩余等)
通过每个XDES Entry和状态的划分,形成了FREE区链表、FREE_FRAG区链表、FULL_FRAG区链表三种链表,这三个是直属于表空间的链表,因此对于所有段来说是共用的
对于FSEG状态的区,也维护了FREE、NOT_FULL、FULL三种链表,分别用于遍历归属于段的空闲页区、归属于段的不满区,归属于段的全满区
因此每个B+树相当于维护了2个段,每个段维护3个归属段的XDES链表,共用3个表空间的XDES链表
而如果是具有一个二级索引的表,即相当于聚簇索引、二级索引两个树,维护4个段,即12个归属段的XDES链表,共用3个表空间的XDES链表,即共15个链表
此外,为了方便找到这些链表,把链表中的一个List Base Node放在表空间的固定位置,想要去遍历就好找了
系统表
InnoDB数据字典
InnoDB使用一些内部系统表存储用户表的元数据,包括以下:
SYS_TABLES:整个InnoDB存储引擎中所有的表的信息
SYS_COLUMNS:整个InnoDB存储引擎中所有的列的信息
SYS_INDEXES:整个InnoDB存储引擎中所有的索引的信息
SYS_FIELDS:整个InnoDB存储引擎中所有的索引对应的列的信息
SYS_FOREIGN:整个InnoDB存储引擎中所有的外键的信息
SYS_FOREIGN_COLS:整个InnoDB存储引擎中所有的外键对应列的信息
SYS_TABLESPACES:整个InnoDB存储引擎中所有的表空间信息
SYS_DATAFILES:整个InnoDB存储引擎中所有的表空间对应文件系统的文件路径信息
SYS_VIRTUAL:整个InnoDB存储引擎中所有的虚拟生成列的信息
评论区