InnoDB数据页结构上

2023-02-28 13:52:49 浏览数 (1)

前面介绍了页的基本信息,mysql为了不同的目的设计了多种不同类型的页,比如存放undo日志的页,存放INODE信息的页等,但是我们更关心存放表记录的页,官方叫索引页(Index),也就是今天的主题,我们还没有介绍过索引,所以为了不让大家引起迷惑,暂时叫数据页吧。

数据结构

页由以上7个部分组成,讲解的顺序由浅入深,不会按照数据存储的顺序来讲述。

数据结构页中记录存储

其中 infimum supremum 与user records 这些是记录。刚开始生成页的时候,没有user records,每插入一条记录,都会从free space 中申请一个记录大小的内存空间,当free space使用完后,这个页也就使用完了。那么页中数据怎么管理的呢?我们以COMPACT行存储方式举例。

记录头

上次我们简单介绍记录头中的信息,这次我们的详细的聊聊。

名称

大小(byte)

描述

预留位1

1

没使用

预留位2

1

没使用

delete_flag

1

0未删除1删除

min_rec_flag

1

B 树每层非叶子节点最小的目录项会添加标记

n_owned

4

页中的记录都会分为不同的组,其中有个记录是带头大哥,其余的是小弟,带头大哥记录的是组内的条数,小弟记录的是0

heap_no

13

记录在页面堆中的相对位置

record_type

3

表示当前记录类型,0普通记录,1B 树非页节点的目录项纪录,2表示Infimum,3表示Supremum

next_record

16

下一条记录真实数据的相对位置

delete_flag

看到这里大家是否有疑问,为啥记录头会有这个属性。原因是因为如果直接物理删除掉后,需要在磁盘重新排序其他记录,会造成性能消耗,所以打个标记来避免。所有被删除的记录会形成一个垃圾链表,记录的空间叫可重用空间,如果有新记录插入,直接复用被删除记录的空间。(至于何时刷新,后续后讲解)

min_rec_flag

B 树每层非叶子节点最小的目录项会添加标记。(聊索引时会重点说)

n_owned

这个暂时保密,稍后它是主角。

heap_no

每一条记录亲密无间的排列的结构叫堆,从第3条用户记录开始根据主键排列,heap_no就是每个记录的在堆里的相对位置。细心的观众会发现为啥从第三条记录开始,是因为每个页都添加了Infimum与Supremum这两条记录。

  • Infimum

存储的内容是固定的单词Infimum由16进制表示。第一条记录,

并且是页面最小的记录。

  • Supremum

存储的内容是固定的单词Supremum由16进制表示。第二条记录,并且是页面最大的记录。

record_type

后续聊到索引的时候我们重点讲。

next_record

表示当前记录的真实数据到下一条真实数据的地址距离。正数在当前地址后面;负数则代表在当前地址前面。有个重点哈,下一条记录不是插入顺序而是主键排序顺序。

  • 删除 细心的会发现,这就是个单向链表,那么删除操作我就不多说了。
  • 新增 会在已删除的空间上直接复用,进行节点添加。

为什么next_record是表示当前记录的真实数据到下一条真实数据的地址距离呢?之前我们聊过行存储,如果还记得,那就非常好理解了,此处重点指针在这,向左是记录头信息,向右是真实数据,而且变成字段列表和null值列表都是字段逆序存放,这样在查询时所需要的信息离在内存中距离更近,提高高速缓存的命中率。

考虑到一口吃不成个胖子,所以余下的后续详细讲述。

0 人点赞