一、页的简介
页是InnoDB 管理存储空间的基本单位,一个页的大小一般是16KB 。为了不同的目的设计了不同的页,比如:存放表空间头部信息的页,存放Insert Buffer信息的页,存放undo 日志信息的页等等。这篇文章主要讲存放表中记录的那种类型的页——索引( INDEX )页。索引是一种为了提高查询速度而设计的数据结构,表中的记录就是数据,所以索引页也叫做数据页。
二、数据页结构
数据页代表的16KB 大小的存储空间可以被划分为多个部分,不同部分有不同的功能。如下:
一个InnoDB 数据页的存储空间大致被划分成了7 个部分,7个部分都存储的内容:
名称 | 中文名 | 占用空间(字节) | 简单描述 |
---|---|---|---|
File Header | 文件头 | 38 | 页的通用信息 |
Page Header | 页面头 | 56 | 数据页专有的信息 |
Infimum + Supremum | 最大、最小记录 | 26 | 两个虚拟的行记录 |
User Records | 用户记录 | 不确定 | 实际存储的行记录内容 |
Free Space | 空闲空间 | 不确定 | 页中尚未使用的空间 |
Page Directory | 页面目录 | 不确定 | 页中的某些记录的相对位置 |
File Trailer | 文件尾 | 8 | 校验页是否完整 |
三、记录在页中的存储
在页的7个组成部分中,自己存储的记录会按照指定的行格式存储到User Records 部分。最开始生成页的时候,并没有User Records部分,每插入一条记录,都会从Free Space部分,即尚未使用的存储空间中申请一个记录大小的空间划分到User Records部分。当Free Space部分的全部空间被User Records部分替代之后,意味这个页用完了,再插入新的记录就需要申请新的页了。
为了更好的管理在User Records 中的这些记录, InnoDB 可费了一番力气呢,在哪费力气了呢?不就是把记录按照指定的行格式一条一条摆在User Records 部分么?其实这话还得从记录行格式的记录头信息中说起。
3.1 记录头信息
先创建一个表page_demo,使用ASCII字符集与Compact行格式:
CREATE TABLE page_demo(
c1 INT,
c2 INT,
c3 VARCHAR(10000),
PRIMARY KEY (c1)
) CHARSET=ascii ROW_FORMAT=Compact;
这个表中记录的行格式示意图就是这样的:
Compact行格式,记录头信息的各个属性的含义:
名称 | 大小(位) | 描述 |
---|---|---|
预留位1 | 1 | 没有使用 |
预留位2 | 1 | 没有使用 |
delete_flag | 1 | 标记该记录是否被删除 |
min_rec_flag | 1 | B+树的每层非叶子节点中的最小记录都会添加该标记 |
n_owned | 4 | 表示当前记录拥有的记录数 |
heap_no | 13 | 表示当前记录在记录堆的位置信息 |
record_type | 3 | 表示当前记录的类型, 0 表示普通记录, 1 表示B+树非叶子节点记录, 2 表示最小记录, 3表示最大记录 |
next_record | 16 | 表示下一条记录的相对位置 |
为了便于理解,只在page_demo 表的行格式演