我们知道InnoDB数据页的基本结构如下所示
在前期文章中我们聊了最小记录、最大记录、用户记录、页面目录的详细结构,往期文章参考
至于剩下的几部分就相对简单了,下面简单了解即可。
主要记录数据页的存储记录状态信息,如页目录中存储了多少个槽,当前数据页存储了多少条记录等等,固定占用56个字节,详细结构说明如下
名称 | 占用字节 | 功能说明 |
---|---|---|
PAGE_N_DIR_SLOTS | 2字节 | 页目录存储槽的数量 |
PAGE_HEAP_TOP | 2字节 | 还未使用的最小空间地址,这个地址往 |
后应该是Free Space空闲空间 | ||
PAGE_N_HEAP | 2字节 | 本页中的记录数(包含正常记录、最大最小记录、已删除记录) |
PAGE_FREE | 2字节 | 第一个已经标记为删除的记录地址(这些已删除记录会 |
通过next_record形成已删除单链表,可以重新利用) | ||
PAGE_GARBAGE | 2字节 | 已经被删除的记录占用字节数 |
PAGE_LAST_INSERT | 2字节 | 最后插入记录的位置 |
PAGE_DIRECTION | 2字节 | 最后一条记录的插入方向,如插入的记录比上一 |
条记录的主键值大,那么插入方向就在右边,反之在左边 | ||
PAGE_N_DIRECTION | 2字节 | 一个方向连续插入的记录数量,当方向改变该值会清空 |
PAGE_N_RECS | 2字节 | 当前页的记录数量(仅为业务记录不包含最 |
小最大记录、已被删除记录) | ||
PAGE_MAX_TRX_ID | 8字节 | 修改当前页的最大事务ID,该值仅在二级索引中定义 |
PAGE_LEVEL | 2字节 | 当前页在B+树中所处的层级 |
PAGE_INDEX_ID | 8字节 | 索引ID,表示当前页属于哪个索引 |
PAGE_BTR_SEG_LEAF | 10字节 | B+树叶子段的头部信息,仅在B+树的Root页定义 |
PAGE_BTR_SEG_TOP | 10字节 | B+树非叶子段的头部信息,仅在B+树的Root页定义 |
上面的数据页头部是仅针对数据页而言,而文件头部则是对于所有的页通用,它描述了各数据页的一些通用信息如页编号、上一页页号和下一页页号等,这部分固定占用38个字节,具体结构如下所示
名称 | 占用字节 | 功能说明 |
---|---|---|
FIL_PAGE_SPACE_OR_CHKSUM | 4字节 | 页的校验和(checksum值) |
FIL_PAGE_OFFSET | 4字节 | 页号,每个页有唯一页号 |
FIL_PAGE_PREV | 4字节 | 上一页的页号 |
FIL_PAGE_NEXT | 4字节 | 下一页的页号 |
FIL_PAGE_LSN | 8字节 | 页面最后被修改时对应的日志序列 |
FIL_PAGE_TYPE | 2字节 | 该页的类型,数据页为FIL_PAGE_INDEX |
十六进制值为0x45BF | ||
FIL_PAGE_FILE_FLUSH_LSN | 8字节 | 仅在系统表空间的一个页中定义,代 |
表文件至少被刷新到了对应的LSN值 | ||
FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID | 4字节 | 页属于哪个表空间 |
这里有个概念校验和,什么叫做校验和呢?
在数据处理和数据通信领域中,用于校验目的地一组数据项的和,通常用来在通信中,尤其远距离通信中保证数据的正确性和完整性。
其实我们在日常中也有过简单使用,如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
我们知道一个数据页普遍的大小是16k,而我们的业务数据可能一个数据页放不下,那么就需要多个数据页存放,将这些可能不连续的数据页关联起来,这里就需要FIL_PAGE_PREV和FIL_PAGE_NEXT,上一页和下一页的页号,那么这就可以组成简单的双向链表,如下所示。
不过需要注意的是除数据页外其它页不一定存在这两个属性值。
因为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值对应,同样也是为了保证数据页的完整性。