在使用 MySQL 时,开发者往往关注的是 SQL 语法层面的 表 (Table) 和 行 (Row)。然而,在 InnoDB 存储引擎的底层,数据是按照 表空间 (Tablespace)、段 (Segment)、区 (Extent) 和 页 (Page) 的层级进行物理管理的。
一、 逻辑架构 vs 物理架构
首先需要明确,MySQL 的存储结构可以分为两个视角:
- 逻辑视角(面向用户):
- 表 (Table):数据的集合容器。
- 行 (Row):业务数据的基本单元。
- 物理视角(面向磁盘):
- 表空间 (Tablespace):物理文件载体。
- 段 (Segment)、区 (Extent)、页 (Page):磁盘空间的管理与分配单位。
二、 物理存储层级详解
InnoDB 的存储结构遵循严格的层级关系:表空间 > 段 > 区 > 页。
1. 表空间 (Tablespace)
表空间是 InnoDB 存储的最顶层容器。
- 物理形态:在开启
innodb_file_per_table(MySQL 5.6+ 默认开启)后,一张表对应一个物理文件(.ibd文件)。 - 作用:该文件包含了表中的所有数据、索引以及元数据信息。
2. 段 (Segment)
段是表空间内的逻辑分区,主要用于管理 B+ 树的节点分布。一个表通常包含两个主要的段:
- 数据段 (Leaf node segment):存放 B+ 树的叶子节点(即真实的行数据)。
- 索引段 (Non-Leaf node segment):存放 B+ 树的非叶子节点(即索引目录)。
- 设计目的:将数据和索引分开管理,确保同一类型的数据在物理上尽可能相邻,提升扫描效率。
3. 区 (Extent)
区是由连续页组成的物理存储块。
- 规格:固定大小 1MB。
- 构成:由 64 个连续的页(16KB * 64)组成。
- 设计目的(关键):
- 为了避免单纯以“页”为单位申请空间导致的磁盘碎片问题。
- 当表中数据量逐渐增大时,InnoDB 会以“区”为单位进行空间申请。这保证了数据在磁盘上的物理连续性,从而将随机 I/O (Random I/O) 优化为 顺序 I/O (Sequential I/O),显著提升范围查询(Range Scan)的性能。
4. 页 (Page)
页是 InnoDB 与磁盘交互的 最小 I/O 原子单位。
- 规格:默认大小 16KB。
- 核心机制:
- I/O 读写:无论业务只需要读取一行数据(几百字节)还是多行,InnoDB 都会将该行所在的整个页(16KB)加载到内存(Buffer Pool)中。
- 内部结构:页内部包含页头 (File Header)、页目录 (Page Directory)、用户记录 (User Records) 等结构。
- B+树关联:在 B+ 树索引结构中,每一个节点本质上就是一个“页”。
三、 逻辑单位:行 (Row) 的物理实现
行 (Row) 是业务逻辑上的最小单位,但在物理存储层面,它并没有独立的物理地址。
- 存储方式:行是存储在 页 (Page) 内部的字节流。
- 行格式 (Row Format):InnoDB 通过特定的行格式(如
Compact或Dynamic)来组织行数据,处理变长字段(VARCHAR)、NULL 值列表以及记录头信息。 - 寻址过程:MySQL 无法直接定位到“某一行”,而是先定位到“页”,将其加载到内存,再通过页目录在内存中通过二分查找找到具体的“行”。
四、 总结:层级关系图谱
各层级之间的包含与管理关系如下:
核心知识点总结:
- 表 逻辑上对应业务集合,物理上对应 .ibd 文件 (表空间)。
- 页 是磁盘 I/O 的最小单位 (16KB),决定了数据库与磁盘交互的粒度。
- 区 是 空间申请的单位 (1MB),存在的意义是为了保证存储的连续性,优化顺序读写性能。
- 行 是 页内的逻辑记录,必须依附于页存在。
全部评论
(0) 回帖