暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

MySQL InnoDB索引页结构

snaily 2021-04-07
1774


InnoDB
管理存储空间的基本单位,一个页的大小一般是16KB


InnoDB
有许多种不同类型的
,如存放表空间头部信息的页,存放Insert Buffer
信息的页,存放INODE
信息的页,存放undo
日志信息的页等等存放记录的页被称为索引(
INDEX
)页


索引页结构:


名称中文名占用空间大小简单描述
File Header文件头部38
字节
页的一些通用信息
Page Header页面头部56
字节
数据页专有的一些信息
Infimum + Supremum最小记录和最大记录26
字节
两个虚拟的行记录
User Records用户记录不确定实际存储的行记录内容
Free Space空闲空间不确定页中尚未使用的空间
Page Directory页面目录不确定页中的某些记录的相对位置
File Trailer文件尾部8
字节
校验页是否完整


Page Directory(页目录)

已知记录在页中按照主键值由小到大顺序串联成一个单链表,InnoDB
将所有正常的记录(包括最大和最小记录,不包括标记为已删除的记录)划分为几个组每个组的最后一条记录(即组内最大的那条记录)的头信息中的n_owned
属性表示该组内共有几条记录,然后将每个组的最后一条记录的地址偏移量单独提取出来按顺序存储到Page Directory
,也就是页目录
。页面目录中的这些地址偏移量被称为
(英文名:Slot
),页面目录就是由
组成的。


分组规则:

  1. 最小记录所在的分组只能有 条记录

  2. 最大记录所在的分组拥有的记录条数为 1~8 条

  3. 其他的分组中记录的条数范围为 4~8 条


示例如图:


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页定义


  • PAGE_DIRECTION

    假如新插入的一条记录的主键值比上一条插入的记录的主键值大,我们说这条记录的插入方向是右边,反之则是左边

  • PAGE_N_DIRECTION

    假设连续几次插入新记录的方向都是一致的,InnoDB
    会把沿着同一个方向插入记录的条数记下来,这个条数就用PAGE_N_DIRECTION
    这个状态表示。如果最后一条记录的插入方向改变了的话,这个状态的值会被清零重新统计。


File Header(文件头部)

记录一些针对各种页都通用的信息,如这个页号,上一个页、下一个页的等等占用固定的38
个字节,
不同类型的页都会以
File Header
作为第一个组成部分


内容如下

名称占用空间大小描述
FIL_PAGE_SPACE_OR_CHKSUM4
字节
页的校验和(checksum值)
FIL_PAGE_OFFSET4
字节
页号
FIL_PAGE_PREV4
字节
上一个页的页号
FIL_PAGE_NEXT4
字节
下一个页的页号
FIL_PAGE_LSN8
字节
页面被最后修改时对应的日志序列位置(英文名:Log Sequence Number)
FIL_PAGE_TYPE2
字节
页的类型
FIL_PAGE_FILE_FLUSH_LSN8
字节
仅在系统表空间的一个页中定义,代表文件至少被刷新到了对应的LSN值
FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID4
字节
页属于哪个表空间


  • FIL_PAGE_SPACE_OR_CHKSUM

    代表当前页面的校验和(checksum)。

    通过某种算法来计算一个比较短的值来代表这个很长的字节串,这个比较短的值就称为校验和
    在比较两个很长的字节串之前先比较这两个长字节串的校验和,如果校验和不一样则两个长字节串肯定不同,省去直接比较两个比较长的字节串的时间损耗。


  • FIL_PAGE_OFFSET

    每一个
    都有一个唯一的页号,InnoDB
    通过页号来定位唯一一个


  • FIL_PAGE_TYPE

    InnoDB
    为了不同的目的而把页分为不同的类型上边介绍的都是存储数据记录的数据页


    具体如下:

    类型名称
    十六进制
    描述
    FIL_PAGE_TYPE_ALLOCATED
    0x0000
    最新分配,还未使用
    FIL_PAGE_UNDO_LOG
    0x0002
    Undo日志页
    FIL_PAGE_INODE
    0x0003
    段信息节点
    FIL_PAGE_IBUF_FREE_LIST
    0x0004
    Insert Buffer空闲列表
    FIL_PAGE_IBUF_BITMAP
    0x0005
    Insert Buffer位图
    FIL_PAGE_TYPE_SYS
    0x0006
    系统页
    FIL_PAGE_TYPE_TRX_SYS
    0x0007
    事务系统数据
    FIL_PAGE_TYPE_FSP_HDR
    0x0008
    表空间头部信息
    FIL_PAGE_TYPE_XDES
    0x0009
    扩展描述页
    FIL_PAGE_TYPE_BLOB
    0x000A
    溢出页
    FIL_PAGE_INDEX
    0x45BF
    索引页,即数据页


  • FIL_PAGE_PREV
    FIL_PAGE_NEXT

    InnoDB
    以页为单位存放数据,数据占用的空间非常大(一张表中可以有成千上万条记录)时,数据可能被分散存储到多个不连续的页中FIL_PAGE_PREV
    FIL_PAGE_NEXT
    分别代表本页的上一个和下一个页的页号这样就建立起一个双向链表把许许多多的页就都串联起来,而无需这些页在物理上真正连着。

    并不是所有类型的页都有上一个和下一个页的属性


    图示如下

    


File Trailer

InnoDB
存储引擎把数据存储到磁盘上,但是磁盘速度太慢,需要以
为单位把数据加载到内存中处理,如果该页中的数据在内存中被修改了,那么在修改后的某个时间需要把数据同步到磁盘中。如果在同步了一半的时候发生断电等意外同步未完成,就会导致数据页中的数据不完整


为了检测一个页是否完整InnoDB
在每个页的尾部都加了一个File Trailer
部分,这个部分由8
个字节组成,分成2个小部分:


  • 前4个字节代表页的校验和

    File Header
    中的校验和相对应的。当一个页面在内存中被修改了,在同步之前先计算它的校验和,校验和会被首先同步到对应磁盘页中的File Header,当完全写完时,校验和也会被写到磁盘File Trailer,如果完全同步成功,则页的File HeaderFile Trailer中的校验和应该是一致的。如果写了一半儿断电了,那么在File Header
    中的校验和就代表着已经修改过的页,而在File Trailer
    中的校验和代表着原先的页,二者不同则意味着同步中间出了错


  • 后4个字节代表页面被最后修改时对应的日志序列位置(LSN)

    页面最后修改时对应的LSN
    也是为了校验页的完整性的

最后修改时间:2021-04-07 14:51:01
文章转载自snaily,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论