【InnoDB 存储引擎】InnoDB 数据页格式(详细版,数据页格式对于理解索引详细的原理很重要)

1 InnoDB 数据页结构

我们已经知道页是 InnoDB 存储引擎管理数据库的最小磁盘单位。页类型为 B-tree Node 的页存放的即是表中行的实际数据了。在这一节

中,我们将从底层具体地介绍 InnoDB 数据页的内部存储结构

InnoDB 数据页由以下7个部分组成:

  • File Header (文件头)
  • Page Header (页头)
  • Infimun 和 Supremum Records
  • User Records (用户记录,即行记录)
  • Free Space (空闲空间)
  • Page Directory (页目录)
  • File Trailer (文件结尾信息)

其中 File HeaderPage HeaderFile Trailer 的大小是固定的,分别为 38、56、8 字节,这些空间用来标记该页的一些信息,如Checksum,数据页所在B+树索引的层数等。User Records、Free Space、Page Directory这些部分为实际的行记录存储空间,因此大小是动态的。在接下来的各小节中将具体分析各组成部分

1.1 File Header

File Header用来记录页的一些头信息,由下表中的8个部分组成,共占用38字节。

名称大小(字节)说明
FIL_PAGE_SPACE_OR_CHKSUM4该值代表页的checksum值
FIL_PAGE_OFFSET4表空间中页的偏移位。如某独立表空间a.ibd的大小为1GB,如果页的大小为16KB,那么总共有65536个页。FIL_PAGE_OFFSET表示该页在所有页中的位置。若此表空间的ID为10,那么搜索页(10,1)就表示查找表a中的第二个页
FIL_PAGE_PREV4当前页的上一个页,B+ Tree特性决定了叶子节点必须是双向列表
FIL_PAGE_NEXT4当前页的下一个页,B+Tree特性决定了叶子节点必须是双向列表
FIL_PAGE_LSN8该值代表该页最后被修改的日志序列位置LSN (Log Sequence Number)
FIL_PAGE_TYPE2InnoDB存储引擎页的类型,记住0x45BF,该值代表了存放的是数据页,即实际行记录的存储空间
FIL_PAGE_FILE_FLUSH_LSN8该值仅在系统表空间的一个页中定义
FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID4该值代表页属于哪个表空间

以从某 ibd 文件捞出来的 File Header 举例如下:

// 用[]框出来范围
3073 0000c000  [87 b8 54 b1 00 00 00 03  ff ff ff ff ff ff ff ff  |..T.............|
3074 0000c010  00 00 00 00 00 2d 8e d7  45 bf 00 00 00 00 00 00  |.....-..E.......|
3075 0000c020  00 00 00 00 00 27] 00 1a  0d c0 80 66 00 00 00 00  |.....'.....f....|
  • FIL_PAGE_SPACE_OR_CHKSUM

    87 b8 54 b1

  • FIL_PAGE_OFFSE

    00 00 00 03

    偏移量是3说明是表空间的低4页

  • FIL_PAGE_PREV

    ff ff ff ff

  • FIL_PAGE_NEXT

    ff ff ff ff

  • FIL_PAGE_LSN

    00 00 00 00 00 2d 8e d7

  • FIL_PAGE_TYPE

    45 bf

    表明是数据页

  • FIL_PAGE_FILE_FLUSH_LSN

    00 00 00 00 00 00 00 00

  • FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID

    00 00 00 27

2.2 Page Header

接着 File Header 部分的是 Page Header,该部分用来记录数据页的状态信息,由14个部分组成,共占用56字节,如下表所示

名称大小(字节)说明
PAGE_N_DIR_SLOTS2在 Page Directory (页目录)中的 Slot (槽)数。后文重点介绍
PAGE_HEAP_TOP2堆中第一个记录的指针,记录在页中是根据堆的形式存放的
PAGE_N_HEAP2堆中的记录数。一共占用2字节,但是第15位指示行记录格式
PAGE_FREE2指向可重用空间的首指针
PAGE_GARBAGE2已删除记录的字节数,即行记录结构中delete flag为1的记录大小的总数
PAGE_LAST_INSERT2最后插入记录的位置
PAGE_DJRECTION2最后插入的方向。
PAGE_N_DIRECTION2一个方向连续插入记录的数量
PAGE_N_RECS2该页中记录的数量
PAGE_MAX_TRX_ID8修改当前页的最大事务ID,注意该值仅在Secondary Index中定义
PAGE_LEVEL2当前页在索引树中的位置,0x00代表叶节点,即叶节点总是在第0层
PAGE_INDEX_ID8索引ID,表示当前页属于哪个索引
PAGE_BTR_SEG_LEAF10B+树数据页非叶节点所在段的segment header。注意该值仅在B+树的Root页中定义
PAGE_BTR_SEG_TOP10B+树数据页所在段的segment header。注意该值仅在B+树的Root页中定义

2.3 Infimum 和 Supremum Record

这个记录还挺重要的

在InnoDB存储引擎中,每个数据页中有两个虚拟的行记录,用来限定记录的边界。Infimum记录是比该页中任何主键值都要小的值,Supremum指比任何可能大的值还要大的值。这两个值在页创建时被建立,并且在任何情况下不会被删除。在Compact行格式和Redundant行格式下,两者占用的字节数各不相同

2.4 User Record 和 Free Space

User Record就是之前讨论过的部分,即实际存储行记录的内容。再次强调,InnoDB存储引擎表总是B+树索引组织的。Free Space很明显指的就是空闲空间,同样也是个链表数据结构。在一条记录被删除后,该空间会被加入到空闲链表中。

2.5 Page Directory(InnoDB 数据页结构最重要的部分)

Page Directory (页目录)中存放了记录的相对位置(注意,这里存放的是页相对位置,而不是偏移量),

在InnoDB中并不是每个记录拥有一个槽,InnoDB存储引擎的槽是一个稀疏目录(sparse directory),即一个槽中可能包含多个记录。伪记录Intimum的n owned值总是为1,记录Supremum的n owned的取值范围为[1, 8 ],其他用户记录n_owned的取值范围为[4, 8]。当记录被插入或删除时需要对槽进行分裂或平衡的维护操作。

在Slots中记录按照索引键值顺序存放,这样可以利用二叉查找迅速找到记录的指针。假设有(‘i’, ‘d’, ‘c’, ‘b’, ‘e’, ‘g’, ‘l’. ‘h’, ‘f’, ‘j’, ‘k’, ‘a’),同时假设一个槽中包含4条记录,则Slots中的记录可能是:(‘a’, ‘e’, ‘i’)。

由于在InnoDB存储引擎中Page Direcotry是稀疏目录,二叉查找的结果只是一个粗略的结果,因此InnoDB存储引擎必须通过recorder header中的next record来继续查找,相关记录。同时,Page Directory很好地解释了 recorder header中的n owned值的含义, 因为这些记录并不包括在Page Directory中。

这里的 Page Directory 与 InnoDB 行记录中的 record header 联系了起来

如何查找一条记录:

1、先在B+数中找到记录所在的页

2、把页加载入内存

3、通过 Page Directory 进行二叉查找。因为 Page Directory 是稀疏的所有只能找到大概位置。

4、在步骤3的基础上继续根据记录偏移量一行一行的查找

因为步骤3,4都是在内存中的操作,且步骤3是二分查找法,因此通常忽略这部分所消耗的时间

2.6 File Trailer

为了检测页是否已经完整地写入磁盘(如可能发生的写入过程中磁盘损坏、机器关机等),InnoDB存储引擎的页中设置了 File Trailer部分。

File Trailer只有一个FIL_PAGE_END_LSN部分,占用8字节。前4字节代表该页的checksum值,最后4字节和File Header中的FIL PAGE LSN相同。将这两个值与File Header 中的 FIL_PAGE_SPACE_OR_CHKSUM 和 FIL_PAGE_LSN 值进行比较,看 是否一致(checksum的比较需要通过InnoDB的checksum函数来进行比较,不是简单的等值比较),以此来保证页的完整性(not corrupted)

2 参考资料

书籍:《InnoDB 存储引擎》,该书电子版书籍作者无套路免费下载

InnoDB 数据页结构(实验):我的文章:《15.6.1 InnoDB 数据页格式(数据页实验,重要).md》


传送门: 保姆式Spring5源码解析

欢迎与作者一起交流技术和工作生活

联系作者

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Fire Fish

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值