在上一篇文章中我们讲了,InnoDB的数据页是InnoDB管理存储空间的基本单位,一个页的大小基本为16kb
那你有没有疑问,就是说这个InnoDB的数据页的结构是什么样的,还有他这些结构分别有那些功能~接下来我们一一讲解
数据页的总览结构
他既然是一个数据页,那咱们总体概括它的结构的时候,就用一个书页来形容~
他自上而下分别是
-
File Header 文件头部 主要作用是保存页的一些通用信息
-
Page Header 页头部 主要作用是保存数据页的一些专有信息
-
Inifmum+Supermum 最小记录+最大记录 两个虚拟的记录
-
User Records 用户记录 主要作用是用户存储的记录内容
-
Free Space 空闲空间 一些还没有使用的空间
-
Page Directory 页目录 主要的作用是页中某些记录的相对位置 asda
-
File Trailer 文件尾部 主要的作用是检查文件是否完整
接下来我们会就这些结构来展开以一个个的讲解,然后3+4统称为记录
下面的讲解我们可能不会按照顺序来进行,先说一下其中的重点记录(3+4)~
记录在页中的存储
我们刚刚说了3+4统称为记录,我们脑子肯定在想,这些记录在页中的流程是什么?那我们就直接上图
其实在一开始的时候,是没有User Records这一用户空间的,原因很简单,就是因为在一开始我们是没有在里面有任何记录的呀~
当我们添加数据之后,就会往页里面插数据,如上图,当User Records满的时候,Free Space就起作用了~但是当这个Free Space使用完了的时候,这个页就已经使用完毕了,我们就需要创建新的页来储存数据
但是我们再思考一下User Records他怎么管理这些数据的,与我们上一章的内容有关
还记得COMPACT行列式吗他是结构是什么?
是不是变长字段长度列表,NULL值列表,记录头信息,真实的数据。
在记录头信息中的秘密
我们先来回忆下记录头信息的结构
一共就5个字节,然后40个二进制位;
他们每个的作用
- delete_mask: 删除标志位,很重要。若此标志位为1,代表这条记录已经被删除了。
- min_mask:B+树非叶子节点中,索引记录的中最小记录。后面讲到索引的时候再说。
- n_owned: 分组里面包含的记录总数,分组后面再说。
- heap_no: 后面再说。
- record_type:很重要,记录的类型(0-普通用户记录,1-索引记录,2-Infimum,3-Supremum)
- next_record: 指针,指向下一条记录,很重要。
这上面不是说heap_no后面再说吗?现在就用到了,记录这个记录在页堆中的相对位置
又有疑问了,什么是堆,设计InnoDB的大叔把下面这种记录紧密排列的结构叫做堆
然后这个heap_no的值为什么我们没有看见0和1记录呢?
这其实是个设计者的小把戏~还记得我们之前说过的Inifmum+Supermum吗?
最小记录与最大记录,他们其实是这个设计者在每条记录前默认加进去的我们可以叫他为伪记录和虚拟记录~
那么我们既然提到了最小与最大,那我就有疑问记录能比较吗?
其实这里我们比较的是主键值的大小,这个东西下一章会详细解释
现在我们讲一下Inifmum与Supremum的结构
他俩的结构其实很简单,就是前面有5个字节的记录头信息+后面的8个字节大小的固定单词哈哈哈哈
Inifmum就他自己,Supermum也是他自己~
另外一点就是heap_no的记录的值在分配之后就不会发生改动了,删掉也不会动。
然后我们说几个比较重要的记录头信息
record_type:很重要,记录的类型(0-普通用户记录,1-索引记录,2-Infimum,3-Supremum)
next_record: 指针,指向下一条记录,很重要
heap_no:记录这个记录在页堆中的相对位置
上面的图片就比较形象了,然后就是如果你删除一条记录的时候他会发生以下事情
- 他的deleted_flag就会变成1
- next_record变成0,也就是意味这没有下一条记录了
- 上一条的next_record指向该记录的下一条next_record
然后就是Suoermum的n_owned值由n变为n-1
Page Directory页目录
这个意思就比如说,我们再看书的时候是不是先看目录,这个也一样,书的目录不是分成一个一个组吗,然后找的想要看的页码,然后去找到目标,设计InnoDB的指挥者也为我们设计了一个类似的东西,制作过程就如下:
- 先把所有的记录分为几个组(但是不包括垃圾链表的记录)
- 然后每个组里的最后一个记录相当于“带头大哥”,组里其他的记录相当于“小弟”,大哥记录里面的头信息的n_owned值为组里一共有多少个记录
- 到现在我们没有提到目录,重头戏来了,将每个组里的最后一条记录的地址偏移量提取出来(啥是地址偏移量:就是这个记录的第0个字节到真实数据之间的距离),按照顺序储存在靠近页尾部的地方,这个地方就是页目录~,页目录里面的这些地址偏移量就叫做槽,每个槽占两个字节,页目录就是由多个槽构成的。
Page Header页面头部
这个地方就是储存数据页的一些特定状态
File Header 文件头部
他这个地方就是存放一些通用的状态
File Trailer 文件尾部
就是前四个字节为校验和
后四个字节代表页最后修改时的对应LSN的后四个字节
用于校验这个文件是否完整
下一章节我们来开始第6章 B+树索引!!!