InnoDB为不同目的设计了很多不同类型的页,比如undo日志信息的页,存放ChangBuffer的页,而存放表中数据记录的页我们称之为数据页。
数据页结构
| 名称 | 中文名 | 占用空间大小 | 描述 |
|---|---|---|---|
| File header | 文件头部 | 38字节 | 页的一些通用信息 |
| Page header | 页面头部 | 56字节 | 数据页专用的一些信息 |
| Infimum+Supremum | 最小记录和最大记录 | 26字节 | 两个虚拟的行记录 |
| User Records | 用户记录 | 不确定 | 实际存储的行记录内容 |
| Free Space | 空闲空间 | 不确定 | 页中尚未使用的空间 |
| Page Directory | 页面目录 | 不确定 | 页中的某些记录的相对位置 |
| File Trailer | 文件尾部 | 8字节 | 校验页是否完整 |
记录在页中的存储
存储的记录会按照指定的行格式存储到User Records中,一开始页生成时没有User Records部分,每当插入一条记录时从Free Space部分申请一个记录大小的空间,将其划分到User Records,当Free Space全部被User Records代替后就意味着该页已经写满,如果此时还有新记录插入,就需要去申请新的页了。
重新看下记录头信息,并详细解释部分项含义
| 名称 | 大小(位) | 描述 |
|---|---|---|
| 预留位1 | 1 | 没有使用 |
| 预留位1 | 1 | 没有使用 |
| delete_flag | 1 | 标识当前记录是否被删除 |
| min_rec_flag | 1 | B+树的每层非叶子节点中的最小记录都会添加该标记 |
| n_owned | 4 | 数据页会将记录分组,组内地址偏移量最大的记录会统计该组的记录数 |
| heap_no | 13 | 表示当前记录在页面堆中的相对位置。 |
| record_type | 3 | 当前记录的类型,0表示普通记录,1表示B+树非叶子节点记录,2表示最小记录(Inflimum),3表示最大记录(Superemum)。 |
| next_record | 16 | 下一条记录的相对位置 |
delete_flag
delete_flag 值为1表示删除,删除之后的记录任然保存在磁盘中,如果将记录从磁盘移除,需要重新漂亮其他记录,会带来性能消耗问题,所以只需要打上删除标记,被删除的记录会形成一个垃圾链表,记录在这个链表中的空间称之为可重用空间,之后若是有新记录插入就有可能覆盖掉被删除记录占用的空间。
heap_no
数据页User Records一条一条数据记录称为堆,记录在堆中的相对位置称之为heap_no,页前面记录的heap_no较小,页后面的heap_no较大。InnoDB在每个页面中加入了两个虚拟记录,一条代表页面的最小记录(Infimum记录),一条代表页面的最大记录(Supremun记录),Infimum记录的heap_no为0,Supremun记录的heap_no为1。
next_record
数据页中的记录是一个按照主键值由小到大顺序串联的单向链表。
n_owned
为了方便根据主键查找页中的某条记录,数据页会将记录分组,组内地址偏移量最大的记录会统计该组的记录数放在n_owned字段,分组相关详情参考页目录内容。
页目录
记录在页中是一个按照主键值由小到大顺序串联的单向链表。为了方便根据主键查找页中的某条记录,创建了页目录的结构:
