InnoDB数据页结构(5)之其它结构

92 阅读5分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第16天,点击查看活动详情

InnoDB数据页结构之其它结构

前言回顾

我们知道InnoDB数据页的基本结构如下所示

在前期文章中我们聊了最小记录、最大记录、用户记录、页面目录的详细结构,往期文章参考

InnoDB数据页结构(1)环境搭建

InnoDB数据页结构(2)之记录头信息解析

InnoDB数据页结构(3)之记录头信息分析

InnoDB数据页结构(4)之页目录

至于剩下的几部分就相对简单了,下面简单了解即可。

Page Header(页面头部)

主要记录数据页的存储记录状态信息,如页目录中存储了多少个槽,当前数据页存储了多少条记录等等,固定占用56个字节,详细结构说明如下

名称占用字节功能说明
PAGE_N_DIR_SLOTS2字节页目录存储槽的数量
PAGE_HEAP_TOP2字节还未使用的最小空间地址,这个地址往 后应该是Free Space空闲空间
PAGE_N_HEAP2字节本页中的记录数(包含正常记录、最大最小记录、已删除记录)
PAGE_FREE2字节第一个已经标记为删除的记录地址(这些已删除记录会通过next_record形成已删除单链表,可以重新利用)
PAGE_GARBAGE2字节已经被删除的记录占用字节数
PAGE_LAST_INSERT2字节最后插入记录的位置
PAGE_DIRECTION2字节最后一条记录的插入方向,如插入的记录比上一
条记录的主键值大,那么插入方向就在右边,反之在左边
PAGE_N_DIRECTION2字节一个方向连续插入的记录数量,当方向改变该值会清空
PAGE_N_RECS2字节当前页的记录数量(仅为业务记录不包含最
小最大记录、已被删除记录)
PAGE_MAX_TRX_ID8字节修改当前页的最大事务ID,该值仅在二级索引中定义
PAGE_LEVEL2字节当前页在B+树中所处的层级
PAGE_INDEX_ID8字节索引ID,表示当前页属于哪个索引
PAGE_BTR_SEG_LEAF10字节B+树叶子段的头部信息,仅在B+树的Root页定义
PAGE_BTR_SEG_TOP10字节B+树非叶子段的头部信息,仅在B+树的Root页定义

File Header(文件头部)

上面的数据页头部是仅针对数据页而言,而文件头部则是对于所有的页通用,它描述了各数据页的一些通用信息如页编号、上一页页号和下一页页号等,这部分固定占用38个字节,具体结构如下所示

名称占用字节功能说明
FIL_PAGE_SPACE_OR_CHKSUM4字节页的校验和(checksum值)
FIL_PAGE_OFFSET4字节页号,每个页有唯一页号
FIL_PAGE_PREV4字节上一页的页号
FIL_PAGE_NEXT4字节下一页的页号
FIL_PAGE_LSN8字节页面最后被修改时对应的日志序列
FIL_PAGE_TYPE2字节该页的类型,数据页为FIL_PAGE_INDEX
十六进制值为0x45BF
FIL_PAGE_FILE_FLUSH_LSN8字节仅在系统表空间的一个页中定义,代表文件至少被刷新到了对应的LSN值
FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID4字节页属于哪个表空间

校验和

这里有个概念校验和,什么叫做校验和呢?

在数据处理和数据通信领域中,用于校验目的地一组数据项的和,通常用来在通信中,尤其远距离通信中保证数据的正确性和完整性。

其实我们在日常中也有过简单使用,如md5校验和常常被用来作为验证传输文件是否完整的算法,简单使用如下

## 创建一个测试文件test.txt内容如下
hello world

## 采用linux自带命令md5sum生成md5值,并且追加到test.md5文件中
[root@root ~]# md5sum test.txt > test.md5

## test.md5文件内容如下
6f5902ac237024bdd0c176cb93063dc4  test.txt

## 检查test.txt是否被修改(没有修改时)
[root@root ~]# md5sum test.txt -c test.md5
md5sum: test.txt: no properly formatted MD5 checksum lines found
test.txt: OK

## 如果将test.txt内容修改再次检验
[root@root ~]# md5sum test.txt -c test.md5
md5sum: test.txt: no properly formatted MD5 checksum lines found
test.txt: FAILED
md5sum: WARNING: 1 computed checksum did NOT match

FIL_PAGE_PREV和FIL_PAGE_NEXT

我们知道一个数据页普遍的大小是16k,而我们的业务数据可能一个数据页放不下,那么就需要多个数据页存放,将这些可能不连续的数据页关联起来,这里就需要FIL_PAGE_PREV和FIL_PAGE_NEXT,上一页和下一页的页号,那么这就可以组成简单的双向链表,如下所示。

不过需要注意的是除数据页外其它页不一定存在这两个属性值。

File Trailer

因为InnoDB存储引擎是将数据以页为单位加载到内存中处理,如果内存中的数据修改了将会同步到磁盘中,但如果同步到一半遇到服务器停电、磁盘损坏等故障就会导致数据页不完整,为此新增了File Trailer部分其目的就是为了保证数据页的完整性。

File Trailer固定占用8个字节,这8个字节分为两个小部分

  • 前四个字节:是和File Header的FIL_PAGE_SPACE_OR_CHKSUM值对应,每当一个页修改了那么在同步前就会得到该页的校验和会先赋值给FIL_PAGE_SPACE_OR_CHKSUM,因为File Header的校验和在前面部分,会先同步到磁盘,如果整个页同步正常,那么最后这两个的校验和将是一致的,反正则说明同步异常。

  • 后四个字节:是和File Header的FIL_PAGE_LSN值对应,同样也是为了保证数据页的完整性。