type
Post
status
Published
date
Feb 5, 2023
slug
summary
tags
数据库
InnoDB
category
学习思考
password
icon
基本格式
- 表文件后缀:ibd
- 除了系统表,其他用户表一个Space对于一个Table
- Table 资源理方式为 Space→Segment →Extent →Page
- 默认一个Page为16kb (可以设置)
- Extent :64个连续
Page,资源管理最小单位。
- XDES(extent descriptor):用于描述
extent
- Segment:描述索引所占用的资源逻辑链表
- Inode Page: 里面存放多条
inode item用于描述segment
- 物理文件可能存储表(索引),UNDOLOG 等。
源码注释 innobase/dict/dict0crea.cc ,在创建新的表会创建4个Page.
page 0是用于描述整个表文件的page,page 1未知,page 2 用于管理表segment,page3聚集索引。
FSP Herader Page
.png?table=block&id=aba12da6-7eda-4461-ac40-6a918904be0f&t=aba12da6-7eda-4461-ac40-6a918904be0f&width=528&cache=v2)
- 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 | ㅤ |

每个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 bytes的Page Number, 2 bytes的Page在整个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