InnoDB 为了避免同的目的而设计了不一样类型的页,咱们把用于存放记录的页叫作索引页html
索引页分为如下部分:mysql
文件头部各个类型的页都有
包含如下部分:sql
名称 | 大小 | 做用 |
---|---|---|
FIL_PAGE_SPACE_OR_CHKSUM | 4 | 页的校验和 (checksum) |
FIL_PAGE_OFFSET | 4 | 页号 (每一个页的都不一样) |
FIL_PAGE_PREV | 4 | 上一个页的页号 |
FIL_PAGE_NEXT | 4 | 下一个页的页号 |
FIL_PAGE_LSN | 8 | 页面被最后修改时对应的日志序列位置 (Log Sequence Number) |
FIL_PAGE_TYPE | 2 | 该页的类型 |
FIL_PAGE_FILE_FLUSH_LSN | 8 | 仅在系统表空间的一个页中定义,表明文件至少被刷新到了对应的 LSN 值 |
FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID | 4 | 页属于哪一个表空间 |
FIL_PAGE_PREV
和 FIL_PAGE_NEXT
表明上一页和下一页的页码,使得多个索引页之间像双向链表同样链接起来设计
页面头部索引页特有的,记录了当前页面的状态信息
包含如下部分:日志
名称 | 大小 (byte) | 做用 |
---|---|---|
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 页定义 |
两个虚拟的行记录,分别位于记录链表的开头和结尾code
用户记录是按照相应行格式存储数据的地方
MySQL 行格式 <- 点击查看htm
以 Compact 为例:
借助 next_record
,记录之间像链表同样链接起来,顺序为主键从小到大排序,第一个为最小记录,最后一条为最大纪录
next_record
指向的是下一纪录真数据开始的地方,也就是下一纪录 next_record
以后blog
当其中的一条记录被删除后,上一条记录的 next_record
指向下一条纪录,此记录标记为删除,next_record
指向 0,当前组最后一条记录 n_owned
更新排序
页目录在靠近页尾部的地方,记录着每组记录中最后一条记录的地址偏移量,每一个偏移量被放在槽 (Slot) 中索引
最小记录所在的分组只能有 1 条记录,最大记录所在的分组拥有的记录条数只能在 1~8 条之间,剩下的分组中记录的条数范围只能在是 4~8 条之间
n_owned
表示当前组中一共有几条记录
因为页目录中记录的主键是有顺序的,因此能够经过二分法进行查找
经过二分法在页目录找到对应的槽,再遍历整个组中的记录
用于确认内存同步到磁盘是否完整
分为两部分:
当一个页面在内存中修改以后,在同步以前须要先计算出校验和
File Header 在页面的前面,因此校验和会先进行同步,File Trialer 在最后进行同步,若是两次校验和不一样说明数据改变了
各个索引页能够按照页中最小主键值从小到大组成一个双向链表,每一个索引页中的记录又会按照主键值从小到大组成一个单链表