🗒️InnoDB 的文件存储格式

2023-2-5|2023-6-7
麦兜
麦兜
type
Post
status
Published
date
Feb 5, 2023
slug
summary
tags
数据库
InnoDB
category
学习思考
password
icon

基本格式

  1. 表文件后缀:ibd
  1. 除了系统表,其他用户表一个Space对于一个Table
  1. Table 资源理方式为 Space→Segment →Extent →Page
  1. 默认一个Page为16kb (可以设置)
  1. Extent :64个连续Page ,资源管理最小单位。
  1. XDES(extent descriptor):用于描述 extent
  1. Segment:描述索引所占用的资源逻辑链表
  1. Inode Page: 里面存放多条 inode item 用于描述 segment
  1. 物理文件可能存储表(索引),UNDOLOG 等。
源码注释 innobase/dict/dict0crea.cc ,在创建新的表会创建4个Page.
page 0是用于描述整个表文件的page,page 1未知,page 2 用于管理表segment,page3聚集索引。

FSP Herader Page

notion image
 
  • FSP_SIZE:表空间大小,以Page数量计算
  • FSP_FREE_LIMIT:目前在空闲的Extent上最小的尚未被初始化的Page的Page Number
  • FSP_FREE:空闲extent链表,该extent内所有page均未被使用。
  • FSP_FREE_FRAG:链表中的每一项为xdes,该extent内有部分page未被使用。
  • FSP_FULL_FRAG:链表中的每一项为xdes,该extent内所有Page均已被使用
  • FSP_SEG_ID:下次待分配的segment id,每次分配新segment时均会使用该字段作为segment id,并将该字段值+1写回
  • FSP_SEG_INODES_FULL:每一项为inode page,该链表中的每个inode page内的inode entry都已经被使用
  • FSP_SEG_INODES_FREE:链表中的每一项为inode page,该链表中的每个inode page内上有空闲inode entry可分配
  • FSP Herader Page里面包含256个 XDES Entry。一个XDES Page为256个 XDES Entry用于监控256个Extent。所以每隔256个Extent便需要一个XDES Page。
 
XDES
Desc
File Segment ID (8)
属于某个段
List node for XDES list (12)
XDES的双链表
State (4)
NOT_INTIED,FREE,FREE_FRAG,FULL_FRAG,XDES_FSEG,XDES_FSEG_FRAG
Page State Bitmap (16) 2 bits per page,1=free,2=clean
notion image
每个extent对应了一个描述它的xdes,且xdes存储在XDES_PAGE之中,每个XDES_PAGE内可存储256个xdes结构,用来描述其后连续256个extent的情况,因此,一旦我们知道了某个extent的起始page no,便可以反推出其对应的xdes所在的page,xdes_calc_descriptor_page()
 

Inode Page

每个inode对应一个segment。每个inode page默认存储FSP_SEG_INODES_PER_PAGE(85)个inode。每个索引使用2个segment,分别用于管理叶子节点和非叶子节点。
 
inode page由page header和inode entry组成,page header为38字节。inode为192字节。
Macro
bits
Desc
FSEG_INODE_PAGE_NODE
12
INODE page在fsp header的某个链表节点,记录前后inode page的位置。该链表为header page的FSP_SEG_INODES_FULL或FSP_SEG_INODES_FREE。
Inode Entry 0
192
inode entry
Inode Entry 1
192
inode entry
……
Inode Entry 84
192
inode entry

Inode Entry

Macro
bits
Desc
FSEG_ID
8
该inode代表的Segment ID,若值为0表示该slot未被使用
FSEG_NOT_FULL_N_USED
8
FSEG_NOT_FULL链表上被使用的Page数量
FSEG_FREE
16
segment上所有page均空闲的extent链表
FSEG_NOT_FULL
16
至少有一个page分配给当前Segment的Extent链表,全部用完时,转移到FSEG_FULL上,全部释放时,则归还给当前表空间FSP_FREE链表
FSEG_FULL
16
segment上page被完全使用的extent链表
FSEG_MAGIC_N
4
Magic Number
FSEG_FRAG_ARR 0
4
存储Page Number。属于该Segment的frag page。总是先从全局分配独立的Page,当填满32个数组项时,就在每次分配时都分配一个完整的Extent,并在XDES PAGE中将其Segment ID设置为当前值
……
……
FSEG_FRAG_ARR 31
4
Segment的第32个Frag Page

文件链表

例如FSP_FREE是一个文件链表,有一个BaseNode包含整个链表元素长度,并且指向第一个元素First和最后一个元素Last。 除了BaseNode多了一个4 bytes的长度标记,其他的元素都具有相同的数据结构,6 bytes分为两部分: 4 bytesPage Number, 2 bytesPage在整个Tablespace的偏移
Base/Node
First/Prev
Page Number(4)
Offset (2)
Base
Length(4)
Last/Next
Page Number(4)
Offset (2)

Q&A

为什么使用Segment、Extent这种方式管理文件资源?
答:使用Segment可以更容易管理那些索引使用了那些资源。使用Extent而不是Page,是因为随着数据增长分配Extent的IO开销比Page小。

创建Segment

实际上创建索引就是创建Segment,然后往索引插入数据就是在Segment分配Page写入数据。
fsp_alloc_seg_inode
 
InnoDB 的索引页结构参数配置不当引起OOM
Loading...