1.1不同类型的页简介
页是InnoDB管理储存空间的基本单位,一个页的大小一般为16kb,InnoDB为了不同的目的从而设计了不同的页。
1.2数据页结构
数据页代表的这块16kb大小的存储空间可以分为多个部分,如下:
(1)FileHeader (38字节) 文件头部 页的一些通用信息
(2)PageHeader (56字节) 页面头部 数据页专有的一些信息
(3)Infimum+Supermum(26字节) 页面中最小和最大的记录
(4)UserRecords (不确定)用户存储的记录内容
(5)FreeSpace (不确定) 空闲空间
(6)PageDirectory(不确定)页目录
(7)File Trailer (8字节) 文件尾部
1.3记录在页中的存储
在七个组成部分中,我们自己存储的记录会按照指定的行格式存储到UserRecords部分。但是在最开始插入时并没有UserRecord部分,每次插入记录时都会向FreeSpace部分申请空间并划分到UserRecords部分,当freespace部分全被UserRecords替代时则代表这个页用完了,再有新纪录需要插入时则需要申请新的页,为了更好的管理UserRecords,其他部分则派上了用场。
1.3.1记录头信息的秘密(记录头信息的属性及描述)
主要属性如下:
deleted_flag :标记当前记录是否被删除占用1比特 0代表未删除 1代表已删除
解析:被删除的记录实际上还是存在于磁盘上的,之所以不能直接从磁盘上移除是因为移除之后还要对其他记录进行重新排列,从而带来性能消耗,所以用一个删除标记来解决这个问题,所有被删除的记录会组成一个垃圾链表,这个链表占用的空间称为可重用空间,之后插入新纪录时就可能覆盖掉这些记录占用的空间。
min_rec_flag : B+树每层叶子结点中最小的目录项记录都会添加该标记
n_owned : 1.4中提及
heap_no : 数据页中的UserRecords部分中的记录是一条挨着一条亲密无间的排列着的,InnoDB的设计者将这个结构称之为堆(heap),为了方便管理将每条记录在堆中的相对位置称之为 heap_no,也就是说前面的记录heap_no相对较小,但是head_no 为0和1的记录是特殊的,分别为
Infimum代表一个页中最小的记录,Supermum代表一个页中最大的记录,设计者规定!!!
也就是说无论插入了多少记录,最大记录和最小记录都是他们两个,而且heap_no分配之后即使删除也不会改变。
record_type : 标识当前记录的类型 共有四种
(1).0代表通用记录
(2)1表示B+树非叶子结点的目录项记录
(3)2表示Infimum记录
(4)3表示Superimum记录
next_record : 表示当前记录的真实数据到达下一个真实数据的距离,正数时代表 当前记录的下一条在当前记录的后面,反之则为前面,也就是说Infimum的后边则为本页中的最小记录,Supermum的前面则为最大记录(本页中),从数据结构来说这是一个单向链表
这里提一句删除记录 假设 当前有三条记录 1指向2 2指向3 如果2被删除则 1指向3 如果再次插入和2相同的记录 则1会重新指向2
注:next_record 指向的位置就在 记录头信息和真实数据之间,因为向左读取就是记录头信息,向右读取就是真实数据
1.4 PageDirectory (页目录)
记录在页中是单项链表,查找记录时不可能遍历所有记录,具体解决如下:
1将左右正常记录(包括Infimum和Supermum但不包括移除带垃圾链表的数据)划分为几个组
2.每个组中最后的记录(也就是最大的记录)相当于“teamleader”,组内其余记录相当于组员n_owned属性表示该组共有几条记录
3.将每个组中最后一条记录的在页面中的地址偏移量(也就是该记录的真实数据与页面中第0字节之间的距离)单独提取出来,按照顺序储存在靠近尾部的地方。这个地方就是PageDirectory,页目录中的地址偏移量称之为槽(slot),每个占用两字节,页目录就是多个槽组成的。
待更新