一栋商业大厦,讲清 InnoDB 的表空间、段、区和页
为什么 InnoDB 已经有了 Page,还需要 Extent 和 Segment?
学习 MySQL 底层原理时,我们经常会遇到 Tablespace、Page、Extent、Segment、XDES、INODE 等概念。
如果只是为了开发业务系统,我们真的需要把它们全部记住吗?
我认为不需要。
我们真正需要的,是理解 InnoDB 如何组织数据、为什么这样设计,以及这些设计如何解释实际开发中遇到的问题。
本文尝试用一栋商业大厦的故事,建立这套心智模型。
阅读说明: 本文基于 MySQL 8.0,默认采用 16KB Page。面向日常业务开发者,重点解释设计思想,不深入讨论源码字段、字节布局等实现细节。
TL;DR:一分钟理解 InnoDB 的空间管理
假设我们把 InnoDB 的表空间想象成一栋商业大厦。
开发商建好大厦之后,需要把它划分成办公室,再把办公室组织成楼层。
小公司可以先租几间办公室,大公司则可以租用整层楼。
而当越来越多的公司入驻后,物业还需要知道:哪些办公室空着、哪些楼层已经出租,以及每家公司拥有多少空间。
InnoDB 面临的也是类似问题。
| InnoDB 概念 | 商业大厦中的角色 | 核心作用 |
|---|---|---|
| Tablespace(表空间) | 整栋商业大厦 | 提供和管理存储空间 |
| Page(页) | 一间办公室 | InnoDB 管理数据的基本单位 |
| Extent(区) | 一整层楼 | 将多个 Page 组织起来,便于批量分配 |
| Segment(段) | 公司里的一个部门 | 管理特定用途的存储空间 |
| XDES、INODE、FSP_HDR | 物业管理系统 | 记录空间的状态和归属 |
在默认配置下:
ini
1 Page = 16KB
1 Extent = 64 Page = 1MB
而这些概念之间,有两个最重要的关系。
第一,物理空间如何组织:
erlang
Tablespace(整栋大厦)
│
├── Extent(楼层)
│ ├── Page(办公室)
│ ├── Page(办公室)
│ └── ...
│
└── Extent(楼层)
├── Page(办公室)
└── ...
第二,空间归谁管理:
css
Segment(某个部门)
│
├── 零散的 Page
│
├── Extent A
│
└── Extent B
这里需要特别注意:
Segment 是逻辑上的空间管理单位,而不是磁盘上一块连续的物理区域。
读完这篇文章,你只需要真正理解这四个概念。至于 XDES、INODE、FSP_HDR 等内部结构,知道它们是用来管理空间的就够了。
一、从一个问题开始:MySQL 的数据到底放在哪里?
先看一张普通的员工表:
sql
CREATE TABLE employee (
id BIGINT PRIMARY KEY,
name VARCHAR(100),
age INT,
KEY idx_age(age)
) ENGINE = InnoDB;
当我们插入一条数据:
sql
INSERT INTO employee VALUES (1, '张三', 25);
这条记录最终保存在哪里?
我们知道,InnoDB 使用 B+Tree 组织索引。
但 B+Tree 是数据结构,它不等于磁盘文件。
总得有一个地方,真正把这些索引节点和记录保存起来。
在 MySQL 8.0 中,InnoDB 默认启用独立表空间:
sql
SHOW VARIABLES LIKE 'innodb_file_per_table';
通常返回:
diff
+-----------------------+-------+
| Variable_name | Value |
+-----------------------+-------+
| innodb_file_per_table | ON |
+-----------------------+-------+
在这种配置下,employee 表通常会使用一个独立的表空间文件:
employee.ibd
其中保存着这张表的数据、索引以及相关管理信息。
我们可以把这个文件想象成一栋商业大厦。
MySQL
│
├── employee.ibd 员工大厦
│
├── orders.ibd 订单大厦
│
└── products.ibd 商品大厦
于是,第一个概念出现了:
Tablespace(表空间),可以理解为整栋商业大厦。
不过,这里要注意:
一张表对应一个独立
.ibd文件,是 MySQL 8.0 默认 File-per-table 模式下的常见情况,并不是所有表空间都只能容纳一张表。
例如,General Tablespace 就可以容纳多张表。
但为了便于理解,接下来我们主要讨论独立表空间。
现在,大厦已经建好了。
接下来要解决的问题是:
数据应该按照什么单位存进去?
二、一间办公室:为什么 InnoDB 需要 Page?
假设你是这栋商业大厦的开发商。
如果整栋大厦都是一个巨大的开放空间,那么每来一家新公司,你都得重新划分区域。
有的公司要 20 平方米,有的要 100 平方米,有的要 500 平方米。
这会让空间管理变得非常麻烦。
于是,你决定把大厦划分成规格统一的办公室。
每间办公室都有自己的编号。
例如:
erlang
员工大厦
│
├── 101 室
├── 102 室
├── 103 室
├── 104 室
└── ...
这样,不管公司大小,都可以按照办公室来分配空间。
InnoDB 的 Page 就相当于这样一间标准化的办公室。
1. Page 是 InnoDB 管理数据的基本单位
默认情况下:
ini
1 Page = 16KB
可以通过 SQL 查看:
sql
SHOW VARIABLES LIKE 'innodb_page_size';
通常得到:
16384
因此,表空间可以理解为由大量 Page 组成:
erlang
employee.ibd
│
├── Page 0
├── Page 1
├── Page 2
├── Page 3
└── ...
不过,一间办公室并不只能坐一个员工。
同样,一个 Page 也不只能保存一条记录。
例如:
sql
INSERT INTO employee VALUES
(1, '张三', 25),
(2, '李四', 28),
(3, '王五', 30);
这些记录可能保存在同一个 Page 中:
一个数据 Page(16KB)
┌──────────────────────────┐
│ 页头等管理信息 │
├──────────────────────────┤
│ 张三的记录 │
│ 李四的记录 │
│ 王五的记录 │
│ ... │
├──────────────────────────┤
│ 页目录等管理信息 │
└──────────────────────────┘
所以,Page 和记录不是一对一的关系。
一页可以保存多条记录,一条记录也可能包含指向其他存储页的页外数据。
2. 这和 B+Tree 有什么关系?
理解 Page 的重要性,关键在于把它和 B+Tree 联系起来。
我们知道,InnoDB 的主键索引是一棵 B+Tree。
markdown
根节点
│
┌───────┴───────┐
│ │
非叶子节点 非叶子节点
│ │
┌──┴──┐ ┌──┴──┐
│ │ │ │
叶子 叶子 叶子 叶子
节点 节点 节点 节点
这里有一个很重要的对应关系:
B+Tree 的节点,在 InnoDB 中通常由 Page 承载。
对于聚簇索引:
- 非叶子页主要保存用于查找的索引记录。
- 叶子页保存完整的行记录。
所以,当我们执行:
ini
SELECT *
FROM employee
WHERE id = 100;
InnoDB 会沿着 B+Tree 查找,最终定位到保存目标记录的叶子页。
这也是为什么学习索引时,总会遇到 Page。
索引的逻辑结构是 B+Tree,真正承载这些节点的是 Page。
3. 为什么理解 Page 很重要?
因为它还能帮我们理解 Buffer Pool。
InnoDB 并不是每次查询记录,都必须重新从磁盘读取数据。
它会通过 Buffer Pool 缓存数据页和索引页。
可以简单理解为:
markdown
磁盘中的 Page
│
▼
Buffer Pool(内存)
│
▼
查询访问 Page 中的记录
当目标 Page 已经缓存在 Buffer Pool 中时,查询就可能直接从内存中读取。
因此,Page 不仅是磁盘上的数据组织单位,也是理解 InnoDB 缓存机制的重要基础。MySQL开发者专区
到这里,关于 Page,我们真正需要记住的是:
Page 是 InnoDB 管理数据的基本单位,默认 16KB;一个 Page 可以保存多条记录,B+Tree 的节点由 Page 承载,Buffer Pool 也以 Page 为基本缓存单位。
这就够了。
没必要现在就去记一个 Page 中每个字段占多少字节。
三、一整层楼:为什么有了 Page,还需要 Extent?
现在,商业大厦开始招商。
最初只有几家小公司,物业每天分配几间办公室就够了。
但后来,一家互联网公司入驻。
负责人说:
我们有 3000 名员工,希望研发团队尽量集中办公。
如果物业仍然一间一间分配办公室,可能出现:
2 楼:研发部 10 人
7 楼:研发部 15 人
13 楼:研发部 8 人
21 楼:研发部 20 人
这样不仅分配起来麻烦,也不利于空间集中管理。
于是物业决定:
对于需要大量空间的公司,直接按整层楼分配。
这就是 Extent 的设计动机。
1. Extent 是一组连续编号的 Page
在默认 16KB Page 下:
ini
1 Extent = 64 Page
也就是:
ini
64 × 16KB = 1MB
我们把一个 Extent 想象成一层楼:
erlang
Extent 0:第 1 层楼
│
├── Page 0
├── Page 1
├── Page 2
├── ...
└── Page 63
于是:
erlang
Tablespace
│
├── Extent 0
│ ├── 64 个 Page
│ └── ...
│
├── Extent 1
│ ├── 64 个 Page
│ └── ...
│
└── Extent 2
├── 64 个 Page
└── ...
这里的 64 个 Page、1MB 是默认 16KB Page 下的结果。
如果修改 innodb_page_size,Extent 中包含的 Page 数量或总大小也可能变化。MySQL开发者专区
2. 为什么不一直按 Page 分配?
假设一个索引不断增长,需要很多新的 Page。
如果每次都单独申请一个 Page,InnoDB 就需要频繁处理空间分配。
当数据规模很大时,这样管理并不理想。
通过 Extent,InnoDB 可以批量分配一组 Page。
就像一家大型企业需要很多办公室时,直接租下一整层,比每增加一个员工就向物业申请一间办公室更方便。
Extent 主要解决的是大规模空间分配与管理问题。
此外,由于 Extent 中的 Page 在表空间文件内连续编号,它也有利于改善空间局部性。
但这里要区分:
连续编号,不等于 B+Tree 中逻辑相邻的页一定物理相邻,也不保证文件系统底层的磁盘块一定连续。
所以,我们不应该简单地认为:
使用 Extent 就能保证范围查询进行顺序 I/O。
更准确的理解是:
Extent 提供了批量管理连续编号 Page 的能力,为空间分配效率和局部性提供基础。
3. 小公司难道也要租整层楼?
这时,一家只有三名员工的创业公司来了。
它只需要几间办公室。
如果物业要求它必须租下整层楼,显然会造成浪费。
所以,大厦还需要一种灵活的出租方式:
小公司可以先租零散办公室,规模变大后再租整层楼。
InnoDB 也有类似机制。
Segment 在较小时,可以先获得零散的 Page,也称为 Fragment Page。
随着空间需求增长,再转向完整 Extent 分配。
你可以把它理解为:
css
创业初期:
Segment
│
├── Page A
├── Page B
└── Page C
规模扩大后:
Segment
│
├── Page A
├── Page B
├── Page C
│
├── Extent 10
└── Extent 25
MySQL 8.0 的官方文档也介绍了 Segment 由单页分配逐步转向整区分配的机制。MySQL开发者专区
至于 Fragment Page 具体能分配多少个、内部如何记录,普通开发者暂时不需要记。
我们只需要理解:
InnoDB 会兼顾小规模空间的利用率和大规模空间的分配效率。
不过,现在又出现了一个新问题。
刚才我们一直在说:
Segment
它到底是什么?
四、公司里的部门:Segment 究竟是什么?
假设一家大型互联网公司租下了商业大厦中的很多办公室。
公司内部有研发部、行政部和财务部。
每个部门都拥有自己的办公空间。
markdown
星辰科技
│
├── 研发部
│ ├── 10 楼
│ ├── 25 楼
│ └── 38 楼
│
├── 行政部
│ ├── 201 室
│ └── 202 室
│
└── 财务部
├── 305 室
└── 306 室
注意这里有一个很重要的特点:
研发部不是一层楼。
研发部是一个组织。
它可以管理第 10 层、第 25 层和第 38 层。
这些楼层不需要连续。
同样,行政部也可以只管理几间零散办公室。
这就是 Segment 最值得理解的地方。
1. Segment 是逻辑空间管理单位
我们经常会看到类似的图:
markdown
Tablespace
↓
Segment
↓
Extent
↓
Page
它很容易让人产生一种误解:
Segment 是一块连续的物理空间,里面再划分成 Extent。
但实际上并不是。
Segment 不代表表空间中某块连续的物理区域。
它更像是一个空间管理者。
它可以管理多个 Extent,也可以管理零散 Page。
例如:
css
某个 Segment
│
├── Fragment Page A
├── Fragment Page B
│
├── Extent 10
├── Extent 25
└── Extent 38
注意:
Extent 10
Extent 25
Extent 38
它们并不连续,但可以属于同一个 Segment。
因此,应该区分两种关系。
物理组织关系:
markdown
Tablespace
└── Extent
└── Page
逻辑管理关系:
markdown
Segment
├── Fragment Page
├── Extent
└── Extent
这是整篇文章最需要建立的心智模型之一。
2. 为什么 InnoDB 需要 Segment?
因为不同用途的 Page,需要分别管理空间。
以前面那张 employee 表为例:
sql
CREATE TABLE employee (
id BIGINT PRIMARY KEY,
name VARCHAR(100),
age INT,
KEY idx_age(age)
) ENGINE = InnoDB;
它有两个索引:
scss
PRIMARY KEY(id)
idx_age(age)
每个索引对应一棵 B+Tree。
而一棵 B+Tree 通常需要分别管理:
叶子节点使用的空间,以及非叶子节点使用的空间。
所以,InnoDB 通常会为每棵 B+Tree 索引分配两个 Segment:
markdown
PRIMARY KEY
│
├── Leaf Segment
│ └── 管理叶子页使用的空间
│
└── Non-leaf Segment
└── 管理非叶子页使用的空间
为什么这么设计?
因为叶子页和非叶子页承担不同任务。
对于聚簇索引:
叶子页保存完整记录,范围查询可能访问大量叶子页。
而非叶子页主要负责查找导航。
把这些空间分别管理,更有利于根据各自的增长特点进行分配。MySQL开发者专区
这就像公司里的不同部门:
虽然都在使用同一栋商业大厦,但各自管理自己需要的空间。
因此,Segment 解决的是空间归属和用途管理的问题。
至于 Segment 具体通过什么数据结构记录这些 Page 和 Extent,我们先不深入。
因为对于大多数业务开发者,理解到这里已经足够了。
五、物业管理系统:那些复杂的 XDES、INODE 需要记住吗?
现在,我们已经建立了整栋商业大厦的基本模型:
整栋楼 → Tablespace
一间办公室 → Page
一整层楼 → Extent
公司部门 → Segment
但我们忽略了一个很现实的问题。
假设这栋大厦有上千层楼,几百家公司入驻。
这时候,物业必须知道:
哪些楼层还没有出租?
哪些楼层还有空办公室?
哪些楼层已经归某个公司管理?
每个公司部门又分别租了哪些楼层?
如果没有管理系统,物业根本无法高效运营这栋大厦。
InnoDB 也是如此。
它不仅需要存储数据,还需要管理存储空间的状态和归属。
于是,就有了 XDES、INODE 和 FSP_HDR 等结构。
对于大多数开发者,我建议理解下面这张表就够了。
| 结构 | 商业大厦中的角色 | 负责什么 |
|---|---|---|
| XDES Entry | 楼层档案 | 描述某个 Extent 的使用状态 |
| INODE Entry | 部门资产登记表 | 管理某个 Segment 拥有的空间 |
| FSP_HDR | 物业总管理中心 | 保存表空间级别的重要管理信息 |
它们之间的关系可以简单理解为:
markdown
Tablespace
整栋大厦
│
▼
FSP_HDR
物业总部
Extent Segment
│ │
▼ ▼
XDES Entry INODE Entry
楼层档案 部门资产档案
实际上,InnoDB 还使用各种链表来组织空闲和已分配的 Extent。
但这篇文章不打算继续展开它们的具体状态和字段。
为什么?
因为我们已经知道了它们存在的原因:
空间会不断分配、使用和回收,因此 InnoDB 必须记录每块空间的状态,并能够快速找到可以继续使用的空间。
知道这一点,就已经建立了正确的基本认知。
如果将来真的需要分析 InnoDB 的空间分配问题,再去研究 XDES、INODE 的内部字段和链表结构,也完全来得及。
理解它为什么存在,比记住它内部长什么样更重要。
六、理解了这些,能解决什么实际问题?
到这里,我们已经认识了四个核心概念。
但如果一篇技术博客只是让我们多记住几个名词,价值仍然有限。
真正重要的是:
这些知识能否帮助我们理解日常开发中遇到的问题?
我们来看一个比较典型的场景。
1. 为什么删除大量数据后,.ibd 文件没有变小?
假设有一张订单表:
sql
CREATE TABLE orders (
id BIGINT PRIMARY KEY,
order_no VARCHAR(64),
create_time DATETIME
) ENGINE = InnoDB;
随着业务发展,订单数据越来越多。
假设其 .ibd 文件已经增长到 20GB。
后来,我们清理了很多历史数据:
sql
DELETE FROM orders
WHERE create_time < '2024-01-01';
删除结束后,发现一个奇怪的现象:
表里的记录少了很多,但 .ibd 文件仍然接近 20GB。
为什么?
如果不了解表空间的管理机制,我们可能会觉得:
数据都删除了,为什么磁盘空间没有释放?
但现在换成商业大厦,就很好理解了。
2. 员工搬走了,不代表大厦会变小
假设星辰科技租下了整栋大厦中的十层楼。
后来,公司裁员,搬走了大量员工。
现在有很多办公室空出来了。
但问题是:
办公室空了,不代表大厦的建筑面积自动缩小了。
物业可能会保留这些空闲办公室,供以后继续出租。
InnoDB 也有类似机制。
当我们删除记录时,相关空间并不一定立即从表空间文件中消失。
经过适当的清理和管理后,部分空间可以被 InnoDB 重新利用。
也就是说:
markdown
DELETE 删除记录
│
▼
相关空间可能逐步变为可重用
│
▼
InnoDB 以后可以利用这些空间
但这和:
markdown
.ibd 文件立即缩小
│
▼
操作系统收回磁盘空间
不是一回事。
这里有两个不同的概念:
空间可重用:
InnoDB 可以在已有表空间内部重新使用某些空间。
文件缩小:
表空间文件实际占用的存储空间减少,操作系统能够收回相应空间。
这两件事并不等价。
MySQL 官方文档也区分了表空间内部的空间重用,以及通过特定操作将磁盘空间返还给操作系统的情况。MySQL开发者专区
3. 那怎样才能让文件缩小?
这里需要区分具体场景。
如果是要清空整张表 ,对于使用独立表空间的 InnoDB 表,TRUNCATE TABLE 通常会删除并重新创建表空间文件,从而将原文件占用的空间返还给操作系统。
但要注意:
sql
TRUNCATE TABLE orders;
会清空整张表的数据,而不是只删除一部分历史记录。
并且它属于 DDL 操作,存在外键约束、事务行为等方面的注意事项。
不要把 TRUNCATE 当成 DELETE 的通用替代品。
如果只删除了一部分记录,又确实需要回收磁盘空间,则可能需要考虑表重建等方案。
不过,是否值得重建,要根据表大小、可用磁盘空间、业务负载、锁影响和操作风险来评估。
这里真正值得记住的,不是具体执行哪条 SQL,而是:
InnoDB 内部空间可以重用,并不意味着
.ibd文件一定会自动缩小。
理解了 Tablespace、Page 和空间管理机制,这个现象就不再神秘了。
4. 还有哪些现象可以用这些知识理解?
例如,当一张表不断插入记录时,索引可能需要新的 Page。
当 B+Tree 叶子页空间不足时,可能发生页分裂。
当索引不断增长,已有空间不够时,InnoDB 就需要继续分配 Page,必要时申请更多 Extent。
于是,表空间文件可能逐渐变大。
可以把它简单理解为:
css
数据不断增加
│
▼
B+Tree 需要更多 Page
│
▼
Segment 需要更多空间
│
▼
InnoDB 分配新的 Page / Extent
│
▼
表空间可能继续增长
实际过程会涉及页分裂、空间重用、Buffer Pool 等机制,比这张图复杂。
但对于初步理解表空间增长,这个模型已经足够。
七、现在,你真正需要记住什么?
我们重新回顾一下。
这篇文章介绍了:
Tablespace
Page
Extent
Segment
XDES
INODE
FSP_HDR
看起来还是有不少名词。
但我希望你读完之后,不要试图把它们全部背下来。
对于普通业务开发者,我认为可以把学习目标分成三个层次。
第一层:必须真正理解
Page
它是 InnoDB 管理数据的基本单位,默认 16KB。
B+Tree 节点由 Page 承载,Buffer Pool 也围绕 Page 缓存数据。
Tablespace
它负责组织和管理数据的存储空间。
默认 File-per-table 模式下,普通表通常使用独立的 .ibd 表空间文件。
这是后续理解索引、缓存、磁盘空间增长的基础。
第二层:理解设计动机即可
Extent
多个 Page 组成一个 Extent,用于批量管理和分配空间。
默认 16KB Page 下,一个 Extent 为 1MB。
Segment
一种逻辑上的空间管理单位。
它按照用途管理 Page 和 Extent,不要求这些空间物理连续。
理解它们的设计动机和相互关系,比记住所有分配规则重要得多。
第三层:知道存在,按需深入
XDES、INODE、FSP_HDR,以及各种空间管理链表。
它们负责描述和管理空间的状态、归属及分配情况。
对于大多数业务开发工作,暂时不需要记住:
- XDES Entry 具体多少字节。
- INODE Entry 有哪些字段。
- 每条 Extent 链表叫什么名字。
- FSP_HDR 各字段的精确偏移量。
- 每种空间状态之间的转换细节。
这些知识不是没有价值,而是不必在当前阶段投入过多学习成本。
等到需要分析表空间文件、研究 InnoDB 源码或者排查底层空间管理问题时,再深入也不迟。
八、写在最后:在 AI 时代,学会建立心智模型比记住细节更重要
回到最开始的商业大厦。
为什么需要 Page?
因为大厦需要标准化的办公室。
为什么需要 Extent?
因为大型企业需要批量分配空间。
为什么需要 Segment?
因为不同部门需要独立管理自己的办公室和楼层。
为什么需要 XDES、INODE、FSP_HDR?
因为空间越来越大,仅仅知道有多少办公室还不够,还需要知道它们的状态和归属。
你会发现:
这些概念并不是为了增加复杂度而存在的,而是在解决不同层次的空间管理问题。
现在,我们把整套知识压缩成一张图:
markdown
InnoDB Tablespace
整栋商业大厦
│
┌─────────────┴─────────────┐
│ │
▼ ▼
物理空间组织 逻辑空间管理
│ │
▼ ▼
Extent Segment
一整层楼 公司部门
│ │
▼ │
Page │
一间办公室 │
▲ │
│ │
└────── 管理 Page / ────────┘
Extent 的归属
XDES / INODE / FSP_HDR
│
▼
空间管理元数据
(物业管理系统)
以后再次遇到这些概念,你不需要回忆某个 XDES 字段的具体含义。
只要先问自己三个问题:
第一,这个概念是在描述空间如何划分吗?
例如 Page、Extent。
第二,它是在描述空间归谁管理吗?
例如 Segment。
第三,它是在描述如何管理这些空间的状态吗?
例如 XDES、INODE、FSP_HDR。
这样,很多原本混在一起的概念,就能够各归其位。
在 AI 时代,我们可以随时查询某个结构的字段定义、源码实现和具体版本差异。
但前提是:
我们知道自己在查什么,也知道如何判断查到的内容是否合理。
这正是基础原理和心智模型的价值。
一名优秀的开发者,不一定能记住 InnoDB 的所有底层结构。
但他应该能够理解:
为什么数据需要组织成 Page,为什么空间需要批量分配,以及为什么删除数据后文件不一定立即缩小。
因为这些理解,可以帮助我们做出正确的技术判断。
原理要理解,关系要搞清,细节可查询,实现按需深入。
这也是我认为在 AI 时代,学习技术知识更值得坚持的方式。
参考资料
本文主要参考 MySQL 8.0 官方文档及 MySQL 官方技术文章:
- MySQL 8.0:InnoDB File Space Management
介绍 Tablespace、Page、Extent、Segment 的基本关系与空间分配方式。 - MySQL 官方技术文章:InnoDB Tablespace Space Management
介绍 Segment、XDES、INODE 等内部空间管理机制。 - MySQL 官方技术文章:Extent Descriptor Page of InnoDB
介绍 Extent 和 XDES 的实现细节。 - MySQL 8.0:InnoDB Buffer Pool
介绍 InnoDB 如何在内存中缓存数据页与索引页。 - MySQL 8.0:Reclaiming Disk Space with TRUNCATE TABLE
介绍 InnoDB 表空间的磁盘空间回收行为。 - 原始学习资料:存放页的大池子------InnoDB 的表空间
下一篇:B+Tree 的一个节点为什么是一个 Page?
如果说本文解决的是:
InnoDB 如何组织和管理存储空间?
那么下一篇就可以继续解决:
这些空间是如何真正保存记录,并支持快速查询的?
我们可以从一个 Page 开始,逐步理解:
- 一条记录在 Page 中是如何组织的?
- B+Tree 为什么能够高效查找?
- Page 空间不足时为什么可能发生页分裂?
- 一次范围查询为什么可能访问多个叶子页?
把这些知识串起来,就能从"空间管理"自然过渡到真正与 SQL 查询性能相关的底层原理。