官方名字:索引页
存储过程
所以你知道了,User Records 和 Free Space 之间是此消彼长的关系
举例
create table demo( c1 int, c2 int, c3 varchar(10000), primary key(c1) )charset=ascii row_format=compact
简化下,因为变长字段长度列表,null值列表都没什么用
所以存储记录为:
* delete_mask:标记是否删除了
* heap_no:记录的序号,序号为0的记录是infimum,序号1为spuermum(这俩是mysql为我们自动提供的),所以我们自己的都是从2开始的,这个排序是通过主键的比较规则来的
* next_record:记录下一条记录的偏移量,下一条记录指的是,按照主键值由小到大的下一天记录。
假如删除一条数据:
那么就等着下一条数据来,直接覆盖就完事了
提问:为什么指针指的是中间位置,哈哈哈,这就是为什么左边的可变长字段长度列表是逆序的原因了,从中间,往两边同时读,刚好都是顺的。自己画图理解下吧。
page_directory
将每个组的最大heap_no的记录偏移地址存在page_directory,这样查找的时候,就可以通过page_directory二分查找,然后再进入相应的组中找,美滋滋。
组的大小一般都是1-8个左右。
page header
数据页中存储的记录的状态信息,比如:存储了多少条记录,第一条记录的地址是什么,有多少个槽
file header
有一个校验和A
还有指向下一个页面
存的都是跟页面有关的信息
file trailer
校验和B
假如现需要将数据页写入磁盘,写到中途断电了,那么校验和A和校验和B势必不一样,那么就说明出错了,只写了一半。
总结
- 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值校验不成功的话,就说名同步失败了。