InnoDB数据页结构 - 图1

File Header 文件头部 38字节 页的一些通用信息
Page Header 页面头部 56字节 数据页专有的一些信息
Infimum + Supremum 最小记录和最大记录 26字节 两个虚拟的行记录
User Records 用户记录 不确定 实际存储的行记录内容
Free Space 空闲空间 不确定 页中尚未使用的空间
Page Directory 页面目录 不确定 页中的某些记录的相对位置
File Trailer 文件尾部 8字节 校验页是否完整

记录在页中的存储

行数据将被存储在User Record中 , 开始时没有这个概念 , 这部分空间称为Free Space , 当有记录需要存入的时候 , 要申请空间 , 当Free Space的空间使用完了就需要申请新的页

记录头信息 (具体的记录头各部分参考 : https://www.yuque.com/u1862289/pxe8ug/ge84yw)

  1. delete_mask

    1. 用于标记记录是否被删除
    2. 占用1个二进制位
    3. 被删除的记录并不会从磁盘上消失 , 而是与其他被删除记录一起组成垃圾链表 , 这部分被称为可重用空间 , 如果有新记录插入可能会将其覆盖
  2. min_rec_mask

    1. 表示是否是B+树中非叶子节点中的最小节点
  3. heap_no

    1. 记录当前记录在本页中的位置
    2. 其中位置的定义是从2开始 , 0和1分别用来记录InnoDB自动插入的两条伪数据 —— 最小记录(Infimum)和最大记录(Supermum)

**

  1. record_type

    1. 0表示普通纪录
    2. 1表示B+树非叶子节点记录
    3. 2表示最小记录
    4. 3表示最大记录
  2. next_record

    1. 表示当前记录真实数据的到下一条记录真实记录的地址偏移量 , 根据当前记录的具体大小往后找记录大小个字节 , 即为下一条真是数据
    2. 下一条记录 , 并不是按照插入顺序 , 而是主键大小的顺序
    3. 一页中的最大最小记录 , 分别在Supermum之前和Infimum之后
    4. 假如第2条记录被删除 , 也就是delete_mask为1时 , 上文说过 , 记录依旧存在于磁盘中 , 此时对于next_record来说 , 偏移量讲直接指向第3条记录 InnoDB数据页结构 - 图2
    5. 不论我们怎么对页中的记录做增删改操作,InnoDB始终会维护一条记录的单链表,链表中的各个节点是按照主键值由小到大的顺序连接起来的

      Page Directory

      为了方便记录的查找 , InnoDB中设计了页目录 , 是一个将记录分组 , 并记录最小最大记录偏移量的一个存储空间 , 其中这些被存放的偏移量称为槽 , 页目录就是由这些槽组成

n_owned

这是未提及的记录头信息中的一部分

  1. 组中的最大记录的n_owned表示该组拥有多少条记录
  2. 最小记录所在的组只能有一条记录 , 即n_owned = 1
  3. 最大记录所在组的记录条目只能在1~8之间
  4. 余下的分组中的记录条目只能为4~8条

记录查找

一个数据页中查找指定主键值的记录过程

  1. 通过二分法确定该记录所在的槽,并找到该槽所在分组中主键值最小的那条记录


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


Page Head

用于存储的记录的信息 , 如多少条记录 , 第一条记录的地址 , 页目录中的槽数量等 , 占用56个字节

image.png

  • page_direction

    • 假如新插入的一条记录的主键值比上一条记录的主键值大,我们说这条记录的插入方向是右边,反之则是左边。用来表示最后一条记录插入方向的状态就是 PAGE_DIRECTION
  • page_n_direction

    • 假设连续几次插入新记录的方向都是一致的,InnoDB会把沿着同一个方向插入记录的条数记下来,这个条数就用PAGE_N_DIRECTION这个状态表示。当然,如果最后一条记录的插入方向改变了的话,这个状态的值会被清零重新统计

如下部分是认为当前没有特殊机制需要详细记录的 , 基本都为功能概念描述 , 不做过多记录


File Head

上述的Page Head是专门针对数据页的信息记录 , 而File Head是对各类型页都通用 , 不同类型的页都会以他来做为第一个组成部分

File Trailer [‘treɪlə]

在数据同步的时候 , 会出现同步不完整的情况 , File Trailer用于记录页是否完整 , 他由8个字节组成 , 分为两部分

  • 前4个字节

    • 这个部分是和File Header中的校验和相对应的。每当一个页面在内存中修改了,在同步之前就要把它的校验和算出来,因为File Header在页面的前边,所以校验和会被首先同步到磁盘,当完全写完时,校验和也会被写到页的尾部,如果完全同步成功,则页的首部和尾部的校验和应该是一致的。如果写了一半儿断电了,那么在File Header中的校验和就代表着已经修改过的页,而在File Trailer中的校验和代表着原先的页,二者不同则意味着同步中间出了错
  • 后4个字节

    • 代表页面被最后修改时对应的日志序列位置(LSN)


  • File Trailer与File Header类似,都是所有类型的页通用的