首页 >> 基础教程

MySQL 的段区页行

            我们来详细拆解一下 MySQL InnoDB 存储引擎中段(Segment)区(Extent)页(Page) 和行(Row) 的概念及其关系。它们是 InnoDB 管理磁盘空间和数据的核心逻辑单元,层级自底向上依次是:行 → 页 → 区 → 段

你可以把它们想象成书本的组织结构:

  • 行 (Row):书中的每一行文字。

  • 页 (Page):书中的一页纸,包含多行文字。

  • 区 (Extent):一叠连续的、固定数量的纸张(页)。

  • 段 (Segment):一个大的章节,由多个“叠纸”(区)组成,专门存放特定类型的内容(如正文、索引)。


1. 行 (Row)

  • 定义: 数据存储的基本单位,对应数据库表中的一条记录

  • 大小: 可变,取决于表中定义的列及其存储的数据。一行记录包含所有列的值(可能包含隐藏列如事务ID、回滚指针)以及行头信息(如删除标记、下一行指针等)。

  • 存储位置: 存储在的内部。

  • 关键点:

    • InnoDB 支持不同的行格式 (COMPACTDYNAMICCOMPRESSEDREDUNDANT),它们影响如何存储变长列(如 VARCHAR、TEXT、BLOB)和 NULL 值,进而影响存储效率和性能。DYNAMIC 是现代版本的默认格式。

    • 对于非常大的变长列(如 TEXT、BLOB),如果一页放不下,DYNAMIC 和 COMPRESSED 格式只会将前 768 字节存储在行内(主页面),剩余部分存储在单独的溢出页中,并通过指针引用。这避免了强制其他行迁移。

    • 每行有一个唯一的 Row ID(如果表没有定义主键或唯一非空索引,InnoDB 会自动生成一个隐藏的 6 字节 Row ID 作为主键)。

2. 页 (Page)

  • 定义: InnoDB 磁盘管理的最小单位,也是内存(Buffer Pool)与磁盘交换数据的基本单位。所有读写操作最终都发生在页级别。

  • 大小: 固定,默认为 16KB。可以在初始化 MySQL 实例时通过 innodb_page_size 配置(通常不建议修改)。

  • 结构: 一个页包含多个部分:

    • File Header: 记录页的元信息,如页号、前后页指针(构成双向链表)、页类型(数据页、索引页、Undo页、系统页等)、属于哪个表空间。

    • Page Header: 记录页内部的状态信息,如槽位信息、记录数、空闲空间起始位置、堆中记录数等。

    • Infimum + Supremum Records: 两个虚拟的行记录,分别表示页中最小和最大的伪记录,用于界定记录的边界。

    • User Records: 实际存储行记录的地方。 记录按照主键顺序(或指定的索引顺序)以单向链表的形式存储(物理上不一定连续,但逻辑有序)。每条记录包含其行头信息列数据

    • Free Space: 页中尚未使用的空间。随着记录的插入而减少,随着记录的删除而增加(但删除的空间可能形成碎片)。

    • Page Directory: 页内记录的稀疏索引(或称为槽 Slots)。它记录了一组指针,指向页中某些特定位置的记录(通常是每隔几条记录取一个)。通过二分查找 Page Directory 可以快速定位到某条记录的大致位置,然后沿着链表顺序查找精确位置。这是页内快速查找的关键。

    • File Trailer: 主要用于校验页数据的完整性(如 Checksum)。

  • 关键点:

    • I/O 单位: 磁盘读写总是以整个页为单位进行的。Buffer Pool 管理的就是这些页在内存中的副本(缓存)。

    • 组织方式: 同一索引的页通过 File Header 中的前后页指针连接成双向链表,逻辑上形成一个有序的集合(按索引键排序)。

    • 页内查找: 通过 Page Directory + 行记录链表 实现高效查找(类似跳表思想)。

    • 页分裂: 当一个已满的页需要插入新记录且没有足够连续空间时,会发生页分裂:大约一半的记录被移动到新申请的页,新记录插入合适的位置,并调整前后页的指针。这是一个开销较大的操作。

    • 页合并: 当相邻页的删除操作导致其利用率很低时,InnoDB 可能会尝试将它们合并,以释放空闲页。

3. 区 (Extent)

  • 定义: 由连续的 64 个页构成的空间单元。默认页大小 16KB 时,一个区的大小为 1MB (64 * 16KB)。

  • 目的:

    • 减少随机 I/O,提高顺序 I/O: 当为表或索引分配新空间时(如插入大量数据),InnoDB 倾向于一次性分配一个完整的区(连续的 64 个页)。因为物理磁盘上连续的数据读取速度远快于随机位置的数据读取。这对于范围扫描(Range Scans)和全表扫描(Full Table Scans)性能至关重要。

    • 减少系统开销: 按区分配比按单个页分配管理起来更高效,减少了空间管理的元数据开销。

  • 关键点:

    • 区是 InnoDB 空间分配(Allocation) 的基本单位。

    • 一个区中的所有页在物理磁盘文件(.ibd 文件)上是连续存储的(至少是逻辑连续的,现代文件系统和 SSD 可能物理不连续,但文件系统会尽量保证)。

    • 段在初始分配时,会一次性申请一个“碎片页”(Fragments Pages)而不是整区,但后续扩展主要按区分配。

4. 段 (Segment)

  • 定义: 一个逻辑概念,是由多个区组成的集合。它是 InnoDB 中表空间内更高一级的管理结构

  • 核心关联: 段与 B+树索引节点类型紧密相关:

    • 叶子节点段 (Leaf Node Segment): 存储 B+树索引中叶子节点的数据。对于聚簇索引(Clustered Index),叶子节点段存储的就是完整的表行数据。对于二级索引(Secondary Index),叶子节点段存储的是索引列的值和对应的主键值。

    • 非叶子节点段 (Non-Leaf Node Segment): 存储 B+树索引中非叶子节点(内部节点) 的数据。这些节点存储的是指向下一层级节点的索引键值和页指针(Page Pointer)。

  • 目的:

    • 逻辑分组: 将属于同一个 B+树索引的不同层级(叶子节点和非叶子节点)的数据组织到不同的段中。这样 InnoDB 可以更灵活地为不同类型的节点数据分配空间和管理策略(例如,叶子节点段通常增长更快)。

    • 空间管理: 段负责管理其下属的区和页的分配、回收和使用情况。

  • 关键点:

    • 创建一个表(主键即聚簇索引)会创建至少两个段:一个叶子节点段(存储行数据),一个非叶子节点段(存储聚簇索引的内部节点)。

    • 创建一个二级索引会额外创建两个段:一个该索引的叶子节点段,一个该索引的非叶子节点段。

    • 段本身在磁盘上没有连续存储的要求,它包含的区可以在表空间文件(.ibd)中分散存放。但区内部的页是连续的。

    • 回滚段 (Rollback Segment): 这是一个特殊的段,用于存储 Undo Log 记录。它包含多个 Undo Slot,每个 Slot 对应一个事务的 Undo Log 链。

    总结:

    1. 层级关系: 行 (Row) → 存储在 → 页 (Page) → 多个连续的页组成 → 区 (Extent) → 多个区(叶子节点区/非叶子节点区)组成 → 段 (Segment) → 多个段(数据段/索引段/回滚段等)存在于 → 表空间 (Tablespace)

    2. 空间分配:

      • 当需要为表或索引新增空间时(如插入数据导致页分裂或新申请空间),InnoDB 首先尝试在相关段中已有的区里找空闲页。

      • 如果没有空闲页,则向表空间申请一个新的区(1MB)加入该段。

      • 初始少量分配可能用“碎片页”,但主要按区分配。

    3. 性能影响:

      • 区: 连续的区分配优化了顺序 I/O,对大规模数据加载和扫描性能至关重要。

      • 页: 页大小影响 I/O 吞吐量和内存利用率。页分裂/合并影响写性能。页内组织(行格式、Page Directory)影响点查和范围查效率。

      • 行: 行格式和溢出机制影响存储密度和读取大字段的性能。

      • 段: 逻辑分离叶子节点和非叶子节点,允许不同的空间增长模式和管理策略。

    理解段、区、页、行的概念,对于深入理解 InnoDB 存储原理、进行性能调优(如避免页分裂、优化 I/O)、理解表空间文件增长以及进行故障诊断都非常重要。

最新文章
InnoDB 和 MyISAM 主要有什么区别?2025-07-06
mysql存储引擎应该怎么选择?2025-07-06
mysql的几种存储引擎2025-07-06
MySQL 的段区页行2025-07-06
一条更新语句是如何执行的?2025-07-06
mysql中一条查询语句是如何执行的?2025-07-02
MySQL基础架构及执行流程解析2025-07-02
MySQL SQL语法树解析过程详解2025-07-02
mysql中SQL 的隐式数据类型转换?2025-07-01
MySQL 第 3-10 条记录怎么查?2025-06-30
备案号:蜀ICP备2023042032号-1