MySQL - 存储引擎之InnoDB磁盘结构

一、InnoDB存储结构

根据架构图可以看出,Innodb主要分为内存结构与磁盘结构两部分

二、InnoDB磁盘结构

Tables(表)

(1)表的物理组织:段(Segment)、区(Extent)、页(Page)
InnoDB通过三级结构管理表空间内的存储资源

  • 页(Page):16KB的物理存储单元,存储行记录或索引
  • 区(Extent):由64个连续页组成(64 × 16KB = 1MB),是分配存储资源的基本单位
  • 段(Segment):由多个区组成,是InnoDB为特定对象(如聚簇索引、二级索引)分配的存储逻辑单元,例如:一张表的聚簇索引对应一个段,每个二级索引也对应一个独立的段
    举例说明:
    一张包含主键和两个二级索引的表,会生成3个段(主键段+两个二级索引段),每个段初始分配1个区(1MB),随着数据增长逐步扩展
    image
    (2)表的定义与存储单元
    InnoDB的表,是逻辑上的数据集合,其物理存储以页(Page)为最小单位(默认16KB)由变量innodb_page_size控制。
    页是InnoDB磁盘I/O的基本操作单元,所有数据(行记录、索引、元数据)均以页的形式存储。
    页的内部结构:
  • 文件头(File Header):描述页的信息,占用38字节
  • 页头(Page Header):页的状态信息,占用56字节
  • 最大和最小记录(Infimum & Supremum):两个虚拟的行记录,占用26字节
  • 用户记录(User Records):存储行记录内容
  • 空闲记录(Free Space):页中还没有被使用的空间
  • 页目录(Page Directory):存储用户记录的相对位置
  • 文件尾(File Trailer):校验页是否完整,占用8字节

Indexes(索引)

聚簇索引
聚簇索引是InnoDB表的核心索引,其B+树结构直接存储数据行,因此一张表只能有一个聚簇索引
(1)结构特点

  • B+树层级:根节点 -> 中间节点 -> 叶子节点,根节点存储索引键的范围,中间节点用于快速定位,叶子节点存储完整数据行
  • 主键强制:聚簇索引的键必须是主键(若未显示定义主键,InnoDB会自动生成隐藏的6字节ROW_ID作为聚簇索引键)
  • 数据顺序:数据行按主键顺序物理存储(逻辑上有序,物理上可能因页分裂调整)
    (2)性能影响
  • 主键选择直接影响查询效率:短主键(如INT)可减少B+树层级(通常3-4层即可覆盖亿级数据),长主键(UUID)会导致页分裂频繁、索引碎片
  • 范围查询(如WHERE id BETWEEN 100 AND 2O0)可利用B+树的顺序特性,通过“索引扫描”高效完成
    非聚簇索引
    非聚簇索引(如普通索引、唯一索引)是独立于聚簇索引的B+树结构,其叶子节点不存储数据行,而是存储聚簇索引键的值
    (1)结构特点
  • B+树结构:与非聚簇索引的键(如name字段)关联,叶子节点存储主键值
  • 回表查询:通过非聚簇索引找到主键后,需再次通过聚簇索引查询完整数据行(称为“回表”)
  • 覆盖索引:若查询仅需非聚簇索引的键值(如SELECT id,name FROM t_user WHERE name = '张三'),则无需回表,直接通过非聚簇索引返回结果(性能最优)
    (2)设计原则
  • 高频查询字段有限:为WHERE、JOIN、ORDER BY中频繁使用的字段建索引
  • 复合索引顺序:遵循“最左匹配原则”(如索引(a,b,c)可优化WHERE a=1、WHERE a=1 AND b=2,但无法优化WHERE b=2)
  • 避免冗余索引:如已有(a,b),无需再建(a)(前者已覆盖后者)

Tablespaces(表空间)

系统表空间(System Tablespaces)

系统表空间是更改缓冲区的存储区域,如果表是在系统表空间而不是每个表文件或通用表空间中创建的,它也可能包含表和索引数据
在MySQL5.x版本当中,还会包含InnoDB数据字典以及Undolog。
涉及参数:innodb_data_file_path

每张表独立表空间(File-Per-Table Tablespaces)

每个表的文件表空间包含单个InnoDB表的数据和索引,并存储在文件系统上的单个数据文件中
独立表空间参数默认开始 ON,不会去放在系统表空间
涉及参数:innodb_file_per_table

通用表空间(General Tablespaces)

通用表空间,需要通过CREATE TABLESPACE语法创建通用表空间,在创建表时,可以指定该表空间
创建语法:CREATE TABLESPACE xxx ADD DATAFILE '${file_name}' ENGINE = ${engine_name};
示例:
image

撤销表空间(Undo Tablespaces)

撤销表空间,MySQL实例在初始化时会自动创建两个默认的undo表空间(初始大小16M),用于存储undo log日志

临时表空间(Temporary Tablespaces)

InnoDB使用会话临时表空间和全局临时表空间,存储用户创建的临时表等数据

双写缓冲区(Doublewrite Buffer Files)

双写缓冲区,InnoDB引擎将数据页从Buffer Pool刷新到磁盘前,先将数据页写入双写缓冲区文件中,便于系统异常时恢复数据

重做日志(Redo Log)

重做日志,用来实现事务的持久性,该日志文件由两部分组成:

  1. 重做日志缓冲(redo log buffer):在内存中
  2. 重做日志文件(redo log):在磁盘中

当事务提交之后会把所有修改信息都会存到该日志中,用于在刷新脏页到磁盘时,发生错误时,进行数据恢复使用

posted @ 2025-08-06 15:07  学弟Craze  阅读(27)  评论(0)    收藏  举报