Innodb索引页文件结构
首先Mysql的基本存储结构是页,Mysql中的存取数据是按照页进行存取的,在查找数据的时候是需要先定位到记录所在页,再从所在页中查找到相应的记录
数据页以一个双向链表维持着顺序,每个数据页以单向链表的格式对记录RowId进行逻辑排序,并且每个数据页之间的记录进行物理排序
由7部分组成
- File Header 文件头,大小固定,为38字节
- Page Header 页头,大小固定,为56字节
- Infimum 和 Supremum Record
- User Records 用户记录
- Free Space 空闲空间
- Page Directory 页目录
- File Trailer 文件结尾信息,大小固定,为8字节
结构说明
File Header文件头
记录页的头信息,大小固定,为38字节,由8部分组成
- FIL_PAGE_SPACE_OR_CHKSUM:4个字节32位checksum保存在header中。
- FIL_PAGE_OFFSET:4个字节,表空间中页的偏移量,Page Number,page初始化时就被保存在header中。
- FIL_PAGE_PREV:4个字节,当前页的上一页,B+Tree特性双向链表
- FIL_PAGE_NEXT:当前页的下一页,B+Tree特性双向链表
- FIL_PAGE_TYPE:2个字节,保存在header中,为了解析page数据,这个字段是必须的,Innodb存储引擎页的类型
- FIL_PAGE_INDEX 十六进制表示为0x45BF,表示为B+树叶节点
- FIL_PAGE_UNDO_LOG 十六进制表示为0x0002,表示为Undo log页
- FIL_PAGE_INODE 十六进制表示为0x0003,表示为索引节点
- FIL_PAGE_IBUF_FREE_LIST 十六进制表示为0x0004,表示为Insert buffer空闲列表
- FIL_PAGE_TYPE_ALLOCATTED 十六进制表示为0x0000,表示为最新分配
- FIL_PAGE_IBUF_BITMAP 十六进制表示为0x0005,表示为Insert buffer位图
- FIL_PAGE_TYPE_SYS 十六进制表示为0x0006,表示为系统页
- FIL_PAGE_TYPE_TRX_SYS 十六进制表示为0x0007,表示为事务系统数据
- FIL_PAGE_TYPE_FSP_HDR 十六进制表示为0x0008,表示为File Space Header
- FIL_PAGE_TYPE_XDES 十六进制表示为0x0009,表示为扩展描述页
- FIL_PAGE_TYPE_BLOB 十六进制表示为0x000A,表示为BLOB页
- FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID:4个字节,保存在header中,space的32位整型唯一编号,代表了该页属于哪个表空间。
- FIL_PAGE_FILE_FLUSH_LSN:8个字节,仅在系统表空间中定义,代表文件至少被更新到了该LSN值,对于独立表空间,该值都为0
- FIL_PAGE_LSN:8个字节,代表该页最后被修改的日志序列位置log sequence number。
Page Header页头
记录数据页的状态信息,大小固定,为56字节,由14部分组成
- PAGE_N_DIR_SLOTS:2个字节,在Page Directory中的slot数
- PAGE_HEAP_TOP:2个字节,堆中第一个记录的指针,记录在页中是根据堆的形式存放的
- PAGE_N_HEAP:2个字节,堆中的记录数,第15位表示行记录格式
- PAGE_FREE:2个字节,指向可重用空间的首指针
- PAGE_GARBAGE:2个字节,已删除记录的字节数,即行记录结构中delete flag为1的记录大小的总数
- PAGE_LAST_INSERT:2个字节,最后插入记录的位置
- PAGE_DIRECTION:2个字节,最后插入的方向
- PAGE_N_DIRECTION:2个字节,一个方向连续插入记录的数量
- PAGE_N_RECS:2个字节,该页中记录的数量
- PAGE_MAX_TRX_ID:8个字节,修改当前页的最大事务ID
- PAGE_LEVEL:2个字节,当前页在索引树中的位置,0x00表示叶节点,即叶节点总是在第一层
- PAGE_INDEX_ID:8个字节,表示当前页属于哪个索引
- PAGE_BTR_SEG_LEAF:10个字节,B+树数据页非叶节点所在段的segment header
- PAGE_BTR_SEGTOP:10个字节,B+树数据页所在段的segment header
Infimum 和 Supremum Record
Innodb中,每个数据页中有两个虚拟的行记录,用来限定记录的边界,Infimum记录是比该页中任何主键值都小的值,Supremum指比任何可能大的值还要大的值,这两个值在页创建的时候被创建
User Records
用户记录是实际存储行记录的内容
Free Space
指的是空闲空间,在一条记录被删除后,该空间会被加入到空闲链表中
Page Directory
页目录中存放了记录的相对位置
File Trailer
为了检测页是否已经完整的写入磁盘,其只有FIL_PAGE_END_LSN部分,占了8个字节,前四个字节代表该页的checksum值,后4个字节和File Header中的FIL_PAGE_LSN相同,通过与File Header中的cheacksum和FIL_PAGE_LSN的值进行比较,来保证页的完整性
拆页
每个数据页之间的记录都是按照RowId物理排序的,如果向一个已满的数据页插入数据就会导致拆页,创建一个新的数据页,将部分数据存放到新的数据页中(所以一般id都使用自增的,就是为了避免频繁的拆页,减少不必要的IO操作)