上篇文章我们说了,索引页分为7个部分,其中free space会给user recoreds分配空间存储真实数据,直到用完申请新的页。查询拥有page directory,会分成不同的槽点,最小槽点有一个值,最大槽点有1~8个值,查询的时候用二分查找法定位id的槽点,然后遍历当前槽点就好。
InnoDB(6)索引页select --mysql从入门到精通(十一)
Page Header(页面头部)
pageHeader就是记录了数据页存放的信息,比如本页已经存储多少数据,第一条记录的地址是什么,页里多少个槽点。所以特意第一位page Header,他是页的第二部分,固定了56个字节,专门存储各种状态,下面看看他各个部分是干嘛的:
- page_n_dir_slots:占用2个字节,页中槽点数量。
- page_heap_top:占用2个字节,还未使用的空间最小地址,也就是说改地址之后就是free space。
- page_n_heap:占用2个字节,本页中的记录数量(包括最小记录,最大记录和删除的记录)。
- page_free:占用2个字节,第一个被标记删除的地址值(以后各个被删除的数据会组成一个单链表,这个单链表的地址值可以重新利用)。
- page_garbage:占用2个字节,已删除记录占用字节。
- page_last_insert:占用2个字节,最后插入记录位子。
- page_direction:占用两个字节,记录插入方向。
- page_n_direction:占用两个字节,一个方向连续插入记录数量。
- page_n_recs:占用两个字节,该页中记录的数量(不包括最大记录最小记录和删除的数据)。
- page_max_trx_id:占用8个字节,修改当前页最大事务id,改值仅在二级索引 中定义。
- page_level:占用2个字节,当前页在b+树中所处的层级。
- page_index_id:占用8个字节,索引id,表示当前页属于哪个索引。
- page_btr_seg_leaf:占用10个字节,b+树叶子段的头部信息,仅在b+树的root页定义。
- page_btr_seg_top:占用10个字节,b+树非叶子段的头部信息,仅在b+树的root页定义。
如果看过前面我的文章,相信大家对page_n_dir_slots,page_last_insert,page_n_recs不陌生了,如果不了解,请先看看前面的文章。其他的不了解暂时没事,后面我们可以慢慢熟悉。
Page_direction:表示最后一条记录插入的方向状态,若比上一条记录主键大,插入方向在右边,若比上一条记录小,插入方向在左边。
Page_n_direction:加入插入几次方向都是一致的,innoDB会沿着同一方向记录下来,如果最后一条记录方向改变,则会吧page_n_direction清零。
File header(文件头部)
上面说了page header是记录页,比如 多少槽,多少记录等。现在file header针对不同类型的页通用,也就是说不同类型的页都以file header作为第一个组成部分,秒速各页通用信息,比如页的编码,他的上一页下一页,占用38个字节。
File_page_space_or_chksum:代表当前页的效验和和cheacksum,啥是效验和?对于一个很长很长的字符串,我们会通过计算用较短的值来代表这个很长的字符串,这就叫效验和。这样比较两个很长字符串直接比较他们效验和就好,提高效率。
File_page_offset:每个页都有唯一性,这就是定位页的唯一性。
File_page_type:代表当前页的类型,innoDB会为了不同的目的吧页分为不同的类型,我们之前介绍过数据页,也就是索引页(file_page_index)。
File_page_prev和file_page_next:因为innoDB不可能用非常大的存储空间存储大量的数据,所以就把数据分到不同的页,为了吧这些不连续的页关联起来,通过file_page_prev和file_page_next组成的双向链表,但不是所有类型的页都有这两个属性,我们介绍的索引页是有的。
File Trailer
我们知道file header里有效验和,而尾部的trailer也有效验和。innoDB会把数据刷新到磁盘上,但因为读写磁盘效率太慢,所以通过页为单位刷新到磁盘。但如果同步了了一半断点怎么办?就是通过trailer的效验和来解决,file trailer有8个字节组成:
- 前四个字节代表效验和:当吧页数据同步到磁盘时候,先会把file header的效验和计算出来,同步到磁盘上,当数据全部同步成功,则吧头部的效验计算给尾部trailer,最后验证这两个效验和是否一致,则同步成功。反之刷新到磁盘一半,断点则会失败。
- 后四个字节代表最后修改时对应的日志序列位置(LSN):这部分也是为了效验文件完整性,后面详细介绍LSN。
File header 和 file trailer是所有类型页的通用页。
总结:
innoDB表为了设计会有不同的页,我们存储数据的页叫索引页:
- file header:存储效验和,页的唯一性,页的类型,及其file_page_prev和file_page_next来组成双向链表,吧不同的页关联起来。
- page header:主要存储页的槽点,和记录值等,每个头部信息都有next record属性,从而使页里的数据串联成一个单链表。
- infimum+supremum:两个虚拟记录,分别记录最小值和最大值,在页的头部信息。
- user recoreds:存储真实数据 的地址,内存从free space申请。
- free space:分配内存给user recoreds。
- page directory:页目录,查询一条数据,不可能从页的第一条数据循环到最后一条,他每个页分为多个槽点,槽0放最小记录,一条数据,最大记录放1~8条数据,其他的放4~8条数据,添加数据过程,每次放入最大记录槽点,当放入第九个时候,则会多分一个槽点,槽0一条数据,槽1有4条数据,槽2最大数据和5条数据。查询的时候用二分查找法,找到对应的槽,从最小索引依次查找。
- file trailer:存储效验和,刷新纪录到磁盘时,先计算file header信息效验和的lsn值到磁盘,当全部数据刷新到磁盘后,在修改trailer的效验和lsn值,最后比较两个lsn值是否一致,一致数据持久化成功。