### 15.11.2 文件空间管理

[](<>)

您在配置文件中定义的数据文件使用[`innodb_data_file_path`](innodb-parameters.html#sysvar_innodb_data_file_path)配置选项形成`InnoDB` [系统表空间](glossary.html#glos_system_tablespace).这些文件在逻辑上连接起来形成系统表空间。使用中没有条带化。您无法定义在系统表空间中分配表的位置。在一个新创建的系统表空间中，`InnoDB`从第一个数据文件开始分配空间。

为避免在系统表空间中存储所有表和索引所带来的问题，您可以启用[`innodb_file_per_table`](innodb-parameters.html#sysvar_innodb_file_per_table)配置选项（默认），它将每个新创建的表存储在单独的表空间文件中（带有扩展名`.ibd`）。对于以这种方式存储的表，磁盘文件内的碎片较少，并且当表被截断时，空间将返回给操作系统，而不是仍然由 InnoDB 在系统表空间中保留。有关详细信息，请参阅[第 15.6.3.2 节，“File-Per-Table 表空间”](innodb-file-per-table-tablespaces.html).

您还可以将表存储在[通用表空间](glossary.html#glos_general_tablespace).通用表空间是使用创建的共享表空间[`创建表空间`](create-tablespace.html)句法。它们可以在 MySQL 数据目录之外创建，能够保存多个表，并支持所有行格式的表。有关详细信息，请参阅[第 15.6.3.3 节，“通用表空间”](general-tablespaces.html).

#### 页面、范围、段和表空间

每个表空间由数据库组成[页面](glossary.html#glos_page).MySQL 实例中的每个表空间都具有相同的[页面大小](glossary.html#glos_page_size).默认情况下，所有表空间的页大小为 16KB；您可以通过指定[`innodb_page_size`](innodb-parameters.html#sysvar_innodb_page_size)创建 MySQL 实例时的选项。您还可以将页面大小增加到 32KB 或 64KB。有关详细信息，请参阅[`innodb_page_size`](innodb-parameters.html#sysvar_innodb_page_size)文档。

这些页面被分组为[范围](glossary.html#glos_extent)对于最大为 16KB 的页面（64 个连续的 16KB 页面，或 128 个 8KB 页面，或 256 个 4KB 页面），大小为 1MB。对于 32KB 的页面大小，extent 大小为 2MB。对于 64KB 的页面大小，extent 大小为 4MB。表空间中的“文件”被称为[细分市场](glossary.html#glos_segment)在`InnoDB`.（这些段不同于[回滚段](glossary.html#glos_rollback_segment)，它实际上包含许多表空间段。）

当一个段在表空间内增长时，`InnoDB`一次将前 32 页分配给它。在那之后，`InnoDB`开始将整个范围分配给段。`InnoDB`一次最多可以将 4 个 extent 添加到一个大段中，以确保数据的良好顺序性。

为每个索引分配两个段`InnoDB`.一种是针对非叶节点的[B树](glossary.html#glos_b_tree)，另一个用于叶节点。保持叶节点在磁盘上的连续性可以实现更好的顺序 I/O 操作，因为这些叶节点包含实际的表数据。

表空间中的某些页包含其他页的位图，因此在一个`InnoDB`表空间不能作为一个整体分配给段，而只能作为单独的页。

当您通过发出[`显示表状态`](show-table-status.html)陈述，`InnoDB`报告表空间中绝对空闲的范围。`InnoDB`始终保留一些范围用于清理和其他内部目的；这些保留区不包括在可用空间中。

当您从表中删除数据时，`InnoDB`收缩相应的 B 树索引。释放的空间是否可供其他用户使用取决于删除模式是否释放单个页面或表空间的范围。删除表或从中删除所有行可以保证将空间释放给其他用户，但请记住，删除的行仅由[清除](glossary.html#glos_purge)操作，在事务回滚或一致读取不再需要它们后的一段时间内自动发生。（看[第 15.3 节，“InnoDB 多版本”](innodb-multi-versioning.html).)

#### 配置保留文件段页面的百分比

这[`innodb_segment_reserve_factor`](innodb-parameters.html#sysvar_innodb_segment_reserve_factor)变量，在 MySQL 8.0.26 中引入，是一个高级功能，允许定义表空间文件段页面保留为空页面的百分比。保留一定百分比的页面以供将来增长，以便可以连续分配 B 树中的页面。修改保留页面百分比的能力允许微调`InnoDB`以解决数据碎片或存储空间使用效率低下的问题。

该设置适用于 file-per-table 和通用表空间。这[`innodb_segment_reserve_factor`](innodb-parameters.html#sysvar_innodb_segment_reserve_factor)默认设置为 12.5%，这与以前的 MySQL 版本中保留的页面百分比相同。

这[`innodb_segment_reserve_factor`](innodb-parameters.html#sysvar_innodb_segment_reserve_factor)变量是动态的，可以使用[`放`](set.html)陈述。例如：

```
mysql> SET GLOBAL innodb_segment_reserve_factor=10;
```

#### 页面与表格行的关系

适用于 4KB、8KB、16KB 和 32KB[`innodb_page_size`](innodb-parameters.html#sysvar_innodb_page_size)设置，最大行长度略小于数据库页面大小的一半。例如，对于默认的 16KB，最大行长度略小于 8KB`InnoDB`页面大小。对于 64KB[`innodb_page_size`](innodb-parameters.html#sysvar_innodb_page_size)设置，最大行长度略小于 16KB。

如果一行未超过最大行长度，则所有行都本地存储在页面内。如果一行超过最大行长，[可变长度列](glossary.html#glos_variable_length_type)选择用于外部页外存储，直到该行符合最大行长度限制。可变长度列的外部页外存储因行格式而异：

-   *紧凑和冗余行格式*

    当为外部页外存储选择可变长度列时，`InnoDB`将前 768 个字节本地存储在行中，其余字节存储在外部溢出页中。每个这样的列都有自己的溢出页列表。768 字节的前缀伴随着一个 20 字节的值，该值存储列的真实长度并指向存储其余值的溢出列表。看[第 15.10 节，“InnoDB 行格式”](innodb-row-format.html).

-   *动态和压缩行格式*

    当为外部页外存储选择可变长度列时，`InnoDB`在行中本地存储一个 20 字节的指针，其余的在外部存储到溢出页中。看[第 15.10 节，“InnoDB 行格式”](innodb-row-format.html).

[`长块`](blob.html)和[`长文`](blob.html)列必须小于 4GB，总行长，包括[`斑点`](blob.html)和[`文本`](blob.html)列，必须小于 4GB。
