一、不同类型的页介绍
InnoDB为了不同的目的设计了多种不同类型的页,例如:存放表空间头部的页面、存放Change Buffer信息的页、存放undo日志信息的页等等索引页(Index)
二、数据页结构快览
数据页的16KB被划分为了7个部分:
- File Header
- 文件头部
- Page Header
- 页面头部
- Infimum + Supremum
- 页面中的最大记录和最小记录
- User Records
- 用户记录
- Free Space
- 空闲空间
- Page Directory
- 页目录
- File Trailer
- 文件尾部
三、记录在页中的存储
一开始并没有User Records
,每当插入一条数据,就会在Free Space
申请一个记录空间的大小,将其划分到User Records
。
1、记录头的信息
delete_flag
标记当前记录是否已被删除
min_rec_flag
B+书每层非叶子节点中的最小目录项都会添加该标记
n_owned
稍后的主角
heap_no
将一条一条亲密无间排列的结构称之为堆空间(heap),从2开始
record_type
当前记录的类型:0-普通记录、1-B+树非叶子结点的目录项记录、2-Infimum记录、3-Supremum记录
next_record
从当前记录的真实数据到下一条记录真实数据的距离,记录是按照主键值从小到大排列的
四、页目录(Page Directory)
记录在页中是按照主键值由小到大的顺序串联成一个单向链表的,如果数据量非常大,查找的效率会非常低,于是引入了在页面内进行分组这种方法
过程如下:
1、将所有的正常记录(包括Infimum和Supremum记录),不包括移除到垃圾链表的记录划分为几个组
2、每个组最后一条记录中的n_owned记录属性表示该组内共有几条记录
3、每个组最后一条记录在页面中的地址偏移被单独提取出来存储,页目录中这些地址的偏移量称之为槽(Slot),每个槽占用两个字节
于是在一个数据页面中查找主键值对应的数据流程为:
1、通过二分法确定记录所在的槽(Slot),然后找到该槽所在分组中主键值最小的那一条记录
2、通过next_record属性遍历槽所在分组的各个记录
五、Page Header(页面头部)
六、File Header(文件头部)
七、File Tailer(文件尾部)
八、总结
InnoDB为了不同的目的设计了不同的页,用于存放数据的页叫做数据页
一个数据页的结构如下:
File Header
页的通用信息
Page Header
数据页的专有信息
Infimum + Supremum
两个虚拟的伪记录,分别表示最大和最小记录
User Records
我们真正插入的数据
Free Space
页中尚未使用的部分
Page Directory
各个槽对应的记录在页面中地址的偏移量
File Trailer
校验页是否完整
InnoDB会将页中的记录划分为若干个组,将每个组的最后一个记录的地址偏移量作为一个槽,存放在Page Directory中
在一个页面中根据主键查找记录分为两步:
1、二分法找到槽,并找到槽所在分组中主键值最小的那条记录
2、通过记录的next_record属性遍历该槽所在的组中的各个记录
所有数据页组成一个双向链表
将页面从内存刷新到磁盘时,为了保证页面的完整性页首和页尾会存储页面的校验和