欲望以提升热忱,毅力以磨平高山!|

navyum

园龄:4个月粉丝:0关注:0

08.数据页结构

基础:

  • 页是InnoDB管理存储空间的基本单位,一个页的大小一般是16KB
  • 数据页(索引页)是页的一种,用来组织和和存放用户数据
  • 索引页之间通过双向链表连接,数据页的物理结构不连续

数据页的详细结构:

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

File Header(文件头部):

  • 文件头组成: |File Header 组成|占用空间大小|描述| |:—-|:—-|:—-| |FIL_PAGE_SPACE_OR_CHKSUM|4字节|页的校验和(checksum值)| |FIL_PAGE_OFFSET|4字节|页号| |FIL_PAGE_PREV|4字节|上一个页的页号,与FIL_PAGE_NEXT构成双向循环列表| |FIL_PAGE_NEXT|4字节|下一个页的页号,与FIL_PAGE_PREV构成双向循环列表| |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_TYPE(页类型): |FIL_PAGE_TYPE 类型名称|十六进制|描述| |:—-|:—-|:—-| |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|change 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|BLOB页,溢出页| |FIL_PAGE_INDEX|0x45BF|索引页,也就是我们所说的数据页|

  • 页之间的连接:FIL_PAGE_PREV + FIL_PAGE_NEXT 构成双向循环链表,不是所有类型的页都有这个

  • 采用链表的结构是让数据页之间不需要是物理上的连续的,但逻辑上可以保持连续 图片

Page Header(页面头部):

Page Header 组成 空间大小 描述
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页定义

Infimum + Supremum:

  • 作用:方便遍历
  • Img
  • mysql 自己创建的两条伪记录
  • 由于这两条记录不是我们自己定义的记录,所以它们并不存放在页的User Records部分,他们被单独放在一个称为Infimum + Supremum的部分
  • 本页中Infimum记录(也就是最小记录)的下一条记录就是本页中主键值最小的用户记录
  • 本页中主键值最大的用户记录的下一条记录就是 Supremum记录(也就是最大记录)

user_records

  • 作用:存放用户记录
  • next_record:
    • 记录之间通过next_record(偏移量)连接,按照主键的大小顺序排成一个单向链表(黑色箭头)
    • next_record记录的是从当前记录的真实数据处到下一条记录的真实数据的地址偏移量(字节)(不是下一条记录的头部)
    • 为什么要指向记录头信息和真实数据之间的位置:这个位置刚刚好,向左读取就是记录头信息,向右读取就是真实数据
    • 本页中Infimum记录(也就是最小记录)的下一条记录就是本页中主键值最小的用户记录
    • 本页中主键值最大的用户记录的下一条记录就是 Supremum记录(也就是最大记录) Img
  • 删除和重用空间
    • 删除的记录,会通过next_record将会把这些被删除掉的记录组成一个垃圾链表,以备之后重用
    • 删除一条记录:
      • 记录并没有从存储空间中直接移除
      • 把该条记录的delete_mask值设置为1
      • next_record值变为了0
      • 修改前一个记录的next_record指向
      • 最大记录Supremum的n_owned值减1
    • 恢复一条记录:
      • 直接复用了原来被删除记录的存储空间

Page Directory(页目录):

  • 作用:通过页目录中槽内的值,可以在页内快速找到目标记录所在的分组,然后从对应分组内最小记录遍历即可(这样就不需要遍历页内的所有记录)
    • 页目录由槽组成
    • 页目录的槽存储的是每个分组中最后一条记录的偏移位置
    • 槽中的数据是顺序排放的 图片
  • 页目录的分组规则:
    • 最小记录(infimun)独立为1组
    • 最大记录(supremum)所在的分组拥有 1~8 条记录
    • 剩下的若干个分组每组可以有 4~8 条记录
    • 初始时有两个槽,即最小记录的槽,最大记录的槽。插入数据后,会放入最大记录的槽
    • 当槽内的记录超过8个,该组会发生分裂,变成两个分组,用两个槽来记录
    • 每组记录用一个槽位记录,组内最大记录的user_records起始位置的偏移量(蓝色箭头)
    • 最大记录的n_owned记录当前组内的记录数
  • 在数据页内查找数据的过程:
    1. 通过二分法确定该记录所在的槽
    2. 找到该槽中主键值最小的那条记录
    3. 通过next_record属性遍历该槽所在的组中的记录找到符合的记录

File Trailer:

  • 作用:解决刷盘过程中断电导致的数据不完整
  • 具体原理:
    • 每当一个页面在内存中修改了,在同步之前就要把它的校验和算出来,因为File Header在页面的前面,所以校验和会被首先同步到磁盘,当完全写完时,校验和也会被写到页的尾部,如果完全同步成功,则页的首部和尾部的校验和应该是一致的。如果写了一半儿断电了,那么在File Header中的校验和就代表着已经修改过的页,而在File Trialer中的校验和代表着原先的页,二者不同则意味着同步中间出了错

本文作者:navyum

本文链接:https://www.cnblogs.com/navyum/p/18509411

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   navyum  阅读(14)  评论(0编辑  收藏  举报
//自己上传到博客园的js
点击右上角即可分享
微信分享提示