Mysql页结构——User Records和Infimum + Supremum

489 阅读3分钟

页的主要作用是存储记录,所以“最大最小记录Infimum + Supremum” 和 “用户记录User Records” 部分占了页结构的主要空间。

User Records(用户记录)

User Records是用来存储数据的地方,简单来说就是怎么把每行数据摆在这个空间里。

当我们新建一个表的时候表中用户记录(用户记录)部分是空的,在外面插入一条记录后会被记录到其中,直到插入满是会把记录信息刷入到下一个页中,往复循环。

User Records 中的这些记录按照指定的行格式一条一条摆放在 User Records 部分,相互之间形成单链表。

记录行格式的记录头信息在摆放数据的过程中发挥了重要的作用,下面是记录头的各个属性:

  • delete_mask 1bit 标记该记录是否被删除,

    • 0 表示记录没有删除,
    • 1 表示记录被删除了
  • min_rec_mask 1bit B+数的每非叶子节点中的最小纪录数都会添加该标记,

    • 只有最小纪录数的min_rec_mask 值为1,
    • 其他别的记录min_rec_mask 值为0
  • n_owned 4bit 如果当前记录是组内最大记录,则代表槽内的记录数

  • heap_no 13bit 当前记录在本页中的位置信息

  • record_type 3bit 表示当前记录的类型,

    • 0表示普通记录,
    • 1表示B+树非叶子节点记录,
    • 2表示最小记录,
    • 3表示最大记录
  • next_record 16bit 表示从当前记录的真实数据到下一条记录的真实数据的地址偏移量。

    比如:第一条记录的next_record值为32,意味着从第一条记录的真实数据的地址处向后找32个字节便是下一条记录的真实数据。

被删除的记录为什么还在页中存储呢?

你以为它删除了,可它还在真实的磁盘上。这些被删除的记录之所以不立即从磁盘上移除,是因为移除它们之后其他的记录在磁盘上需要重新排列,导致性能消耗。所以只是打一个删除标记而已,所有被删除掉的记录都会组成一个所谓的==垃圾链表==,在这个链表中的记录占用的空间称之为==可重用空间==,之后如果有新记录插入到表中的话,可能把这些被删除的记录占用的存储空间覆盖掉。

关于heap_no值为0和1的记录

MySQL会自动给每个页里加了两个记录,由于这两个记录并不是我们自己插入的,所以有时候也称为伪记录或者虚拟记录。这两个伪记录一个代表最小记录,一个代表最大记录。最小记录和最大记录的heap_no值分别是0和1,也就是说它们的位置最靠前。

Infimum + Supremum(最小最大记录)

比较记录的大小就是比较主键的大小。

InnoDB规定的最小记录与最大记录这两条记录的构造十分简单,都是由5字节大小的记录投信息和8个字节大小的一个固定的部分组成的:

在这里插入图片描述

定Infimum记录(也就是最小记录)的下一条记录就是本页中主键值最小的用户记录,而本页中主键值最大的用户记录的下一条记录就是Supremum记录(也就是最大记录)。