页是MySQL管理存储空间的基本单位,一个页的大小一般是16KB,并且记录其实是被存放在页中。
如果记录占用的空间太大还可能造成行溢出现象,这会导致一条记录被分散存储在多个页中。
数据页结构的快速浏览
页的本质就是一块16KB大小的存储空间
InnoDB为了不同的目的而把页分为不同的类型,
其中用于存放记录的页也称为数据页,
数据页代表的这块16KB大小的存储空间可以被划分为多个部分,不同部分有不同的功能,各个部分如图所示:
名称 | 中文名 | 占用空间 | 描述 |
---|---|---|---|
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部分替代掉之后,也就意味着这个页使用完了,如果还有新的记录插入的话,就需要去申请新的页了
过程的图示如下:
总结
InnoDB为了不同的目的而设计了不同类型的页,用于存放我么记录的页也叫做数据页。
一个数据页可以被分为7个部分,分别是
- File Header,表示文件头,占固定的38字节。
- Page Header,表示页里的一些状态信息,占固定的56个字节。
- Infimum + Supremum,两个虚拟的伪记录,分别表示页中的最小和最大记录,占固定的26个字节。
- User Records:真实存储我们插入的记录的部分,大小不固定。
- Free Space:页中尚未使用的部分,大小不确定。
-Page Directory:页中的记录相对位置,也就是各个槽在页面中的地址偏移量,大小不固定,插入的记录越多,这个部分占用的空间越多。 - File Trailer:用于检验页是否完整的部分,占用固定的8个字节。
- 每个记录的头信息中都有一个next_record属性,从而使页中的所有记录串联成一个单链表。
- InnoDB会为把页中的记录划分为若干个组,每个组的最后一个记录的地址偏移量作为一个槽,存放在Page Directory中,所以在一个页中根据主键查找记录是非常快的,分为两步:
- 通过二分法确定该记录所在的槽。
- 通过记录的next_record属性组成的链表遍历查找该槽中的各个记录。
每个数据页的File Header部分都有上一个和下一个页的编号,所以所有的数据页会组成一个双链表。
为保证从内存中同步到磁盘的页的完整性,在页的首部和尾部都会存储页中数据的校验和和LSN值,如果首部和尾部的校验和和LSN值校验不成功的话,就说明同步过程出现了问题。