一、不同类型的页介绍

InnoDB为了不同的目的设计了多种不同类型的页,例如:存放表空间头部的页面、存放Change Buffer信息的页、存放undo日志信息的页等等索引页(Index)

二、数据页结构快览

数据页的16KB被划分为了7个部分:

  • File Header
    • 文件头部
  • Page Header
    • 页面头部
  • Infimum + Supremum
    • 页面中的最大记录和最小记录
  • User Records
    • 用户记录
  • Free Space
    • 空闲空间
  • Page Directory
    • 页目录
  • File Trailer
    • 文件尾部

三、记录在页中的存储

一开始并没有User Records,每当插入一条数据,就会在Free Space申请一个记录空间的大小,将其划分到User Records

1、记录头的信息

  • delete_flag

    标记当前记录是否已被删除

  • min_rec_flag

    B+书每层非叶子节点中的最小目录项都会添加该标记

  • n_owned

    稍后的主角

  • heap_no

    将一条一条亲密无间排列的结构称之为堆空间(heap),从2开始

  • record_type

    当前记录的类型:0-普通记录、1-B+树非叶子结点的目录项记录、2-Infimum记录、3-Supremum记录

  • next_record

    从当前记录的真实数据到下一条记录真实数据的距离,记录是按照主键值从小到大排列的

四、页目录(Page Directory)

记录在页中是按照主键值由小到大的顺序串联成一个单向链表的,如果数据量非常大,查找的效率会非常低,于是引入了在页面内进行分组这种方法

过程如下:

1、将所有的正常记录(包括Infimum和Supremum记录),不包括移除到垃圾链表的记录划分为几个组

2、每个组最后一条记录中的n_owned记录属性表示该组内共有几条记录

3、每个组最后一条记录在页面中的地址偏移被单独提取出来存储,页目录中这些地址的偏移量称之为槽(Slot),每个槽占用两个字节

于是在一个数据页面中查找主键值对应的数据流程为:

1、通过二分法确定记录所在的槽(Slot),然后找到该槽所在分组中主键值最小的那一条记录

2、通过next_record属性遍历槽所在分组的各个记录

五、Page Header(页面头部)

六、File Header(文件头部)

七、File Tailer(文件尾部)

八、总结

InnoDB为了不同的目的设计了不同的页,用于存放数据的页叫做数据页

一个数据页的结构如下:

  • File Header

    页的通用信息

  • Page Header

    数据页的专有信息

  • Infimum + Supremum

    两个虚拟的伪记录,分别表示最大和最小记录

  • User Records

    我们真正插入的数据

  • Free Space

    页中尚未使用的部分

  • Page Directory

    各个槽对应的记录在页面中地址的偏移量

  • File Trailer

    校验页是否完整

InnoDB会将页中的记录划分为若干个组,将每个组的最后一个记录的地址偏移量作为一个槽,存放在Page Directory中

在一个页面中根据主键查找记录分为两步:

1、二分法找到槽,并找到槽所在分组中主键值最小的那条记录

2、通过记录的next_record属性遍历该槽所在的组中的各个记录

所有数据页组成一个双向链表

将页面从内存刷新到磁盘时,为了保证页面的完整性页首和页尾会存储页面的校验和