Documentation Home
MySQL 8.3 Reference Manual
Related Documentation Download this Manual
PDF (US Ltr) - 40.8Mb
PDF (A4) - 40.9Mb
Man Pages (TGZ) - 294.0Kb
Man Pages (Zip) - 409.0Kb
Info (Gzip) - 4.0Mb
Info (Zip) - 4.0Mb
Excerpts from this Manual

MySQL 8.3 Reference Manual  /  ...  /  CREATE TABLESPACE Statement

15.1.21 创建表空间语句

CREATE [UNDO] TABLESPACE tablespace_name

  InnoDB and NDB:
    [ADD DATAFILE 'file_name']
    [AUTOEXTEND_SIZE [=] value]

  InnoDB only:
    [FILE_BLOCK_SIZE = value]
    [ENCRYPTION [=] {'Y' | 'N'}]

  NDB only:
    USE LOGFILE GROUP logfile_group
    [EXTENT_SIZE [=] extent_size]
    [INITIAL_SIZE [=] initial_size]
    [MAX_SIZE [=] max_size]
    [NODEGROUP [=] nodegroup_id]
    [WAIT]
    [COMMENT [=] 'string']

  InnoDB and NDB:
    [ENGINE [=] engine_name]

  Reserved for future use:
    [ENGINE_ATTRIBUTE [=] 'string']

该语句用于创建表空间。精确的语法和语义取决于所使用的存储引擎。在标准的 MySQL 版本中,这总是 InnoDB 表空间。MySQL NDB Cluster 也支持使用 NDB 存储引擎的表空间。

InnoDB 的考虑事项

CREATE TABLESPACE 语法用于创建通用表空间或撤销表空间。必须指定 UNDO 关键字以创建撤销表空间。

通用表空间是一个共享表空间。它可以容纳多个表,并支持所有表行格式。通用表空间可以在数据目录相对或独立的位置创建。

创建 InnoDB 通用表空间后,使用 CREATE TABLE tbl_name ... TABLESPACE [=] tablespace_nameALTER TABLE tbl_name TABLESPACE [=] tablespace_name 将表添加到表空间中。有关更多信息,请参阅 第 17.6.3.3 节,“通用表空间”

撤销表空间包含撤销日志。撤销表空间可以在选择的位置创建,方法是指定一个完全限定的数据文件路径。有关更多信息,请参阅 第 17.6.3.4 节,“撤销表空间”

NDB Cluster 的考虑事项

该语句用于创建表空间,可以包含一个或多个数据文件,为 NDB 集群磁盘数据表提供存储空间(参见 第 25.6.11 节,“NDB 集群磁盘数据表”)。使用该语句创建一个数据文件并将其添加到表空间中。可以使用 ALTER TABLESPACE 语句(参见 第 15.1.10 节,“ALTER TABLESPACE 语句”)添加更多数据文件到表空间中。

Note

所有 NDB 集群磁盘数据对象共享同一个命名空间。这意味着 每个磁盘数据对象 都必须具有唯一的名称(而不仅仅是每个磁盘数据对象的类型)。例如,您不能拥有一个名为同名的表空间和日志文件组,或者一个名为同名的表空间和数据文件。

必须将一个或多个 UNDO 日志文件组分配给要创建的表空间,使用 USE LOGFILE GROUP 子句。logfile_group 必须是一个使用 CREATE LOGFILE GROUP 创建的现有日志文件组(参见 第 15.1.16 节,“CREATE LOGFILE GROUP 语句”)。多个表空间可以使用同一个日志文件组进行 UNDO 日志记录。

设置 EXTENT_SIZEINITIAL_SIZE 时,可以选择性地在数字后面添加一个字母缩写,类似于 my.cnf 中使用的缩写。通常,这是一个字母,例如 M(用于兆字节)或 G(用于吉字节)。

INITIAL_SIZEEXTENT_SIZE 都会进行四舍五入,如下所示:

  • EXTENT_SIZE 向上舍入到最近的 32K 的整数倍。

  • INITIAL_SIZE 向下舍入到最近的 32K 的整数倍;然后将结果向上舍入到最近的 EXTENT_SIZE 的整数倍(在任何舍入后)。

Note

NDB 为数据节点重新启动操作保留表空间的 4%。这部分保留的空间不能用于数据存储。

刚才描述的舍入操作是明确执行的,并且当 MySQL 服务器执行任何这种舍入操作时都会发出警告。舍入后的值也被 NDB 内核用于计算 信息架构.FILES 列值和其他目的。然而,为避免意外结果,我们建议您总是使用 32K 的整数倍来指定这些选项。

当使用 CREATE TABLESPACEENGINE [=] NDB 时,在每个集群数据节点上创建了一个表空间和关联的数据文件。您可以通过查询信息架构 FILES 表来验证数据文件是否创建并获取关于它们的信息。(见本节后面的示例。)

(见 第 28.3.15 节,“信息架构 FILES 表”。)

选项

  • ADD DATAFILE:定义表空间数据文件的名称。此选项在创建 NDB 表空间时总是必需的;对于 InnoDB,只有在创建撤销表空间时才需要该选项。文件名,包括任何指定的路径,必须用单引号或双引号括起来。文件名(不包括文件扩展名)和目录名必须至少一个字节长。零长度文件名和目录名不受支持。

    由于 InnoDBNDB 对数据文件的处理方式存在很大差异,因此在下面的讨论中将这两个存储引擎分开处理。

    InnoDB 数据文件。 一个 InnoDB 表空间仅支持单个数据文件,其名称必须包括 .ibd 扩展名。

    要将 InnoDB 通用表空间数据文件放在数据目录之外的位置,请包括一个完整的路径或相对于数据目录的路径。只有完整的路径才允许用于撤销表空间。如果您不指定路径,将在数据目录中创建一个通用表空间。未指定路径的撤销表空间将创建在由 innodb_undo_directory 变量定义的目录中。如果 innodb_undo_directory 变量未定义,撤销表空间将创建在数据目录中。

    为了避免与隐式创建的每个表文件表空间冲突,在数据目录下的子目录中创建通用表空间 InnoDB 不被支持。当在数据目录外创建通用表空间或撤销表空间时,目录必须存在并且必须在创建表空间之前被 InnoDB 所知晓。要使目录被 InnoDB 所知晓,添加到 innodb_directories 值或添加到附加到 innodb_directories 值的变量中。innodb_directories 是一个只读变量。配置它需要重新启动服务器。

    如果在创建 InnoDB 表空间时未指定 ADD DATAFILE 子句,将隐式创建一个具有唯一文件名的表空间数据文件。唯一文件名是一个 128 位 UUID,格式化为五组十六进制数字,分隔符为破折号 (aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee)。如果需要,存储引擎将添加文件扩展名。.ibd 文件扩展名将被添加到 InnoDB 通用表空间数据文件中。在复制环境中,复制源服务器上创建的数据文件名与副本服务器上创建的数据文件名不同。

    创建 InnoDB 表空间时,ADD DATAFILE 子句不允许循环目录引用。例如,以下语句中的循环目录引用 (/../) 不被允许:

    CREATE TABLESPACE ts1 ADD DATAFILE ts1.ibd 'any_directory/../ts1.ibd';

    在 Linux 上存在一个例外情况,即如果前一个目录是符号链接,那么循环目录引用将被允许。例如,如果 any_directory 是符号链接,那么数据文件路径在上面的示例中将被允许。(数据文件路径仍然可以以 '../' 开头。)

    NDB 数据文件。 一个 NDB 表空间支持多个数据文件,可以具有任何合法的文件名;可以使用 ALTER TABLESPACE 语句在创建 NDB 集群表空间后添加更多数据文件。

    一个 NDB 表空间数据文件默认创建在数据节点文件系统目录中,即数据节点数据目录 (DataDir) 下的名为 ndb_nodeid_fs/TS 的目录中,其中 nodeid 是数据节点的 NodeId。要将数据文件放在默认位置以外的位置,请包括绝对目录路径或相对于默认位置的路径。如果指定的目录不存在,NDB 将尝试创建它;系统用户账户在运行数据节点进程时必须具有适当的权限来执行此操作。

    Note

    在确定数据文件的路径时,NDB 不会展开 ~ (tilde) 字符。

    当在同一物理主机上运行多个数据节点时,以下考虑事项适用:

    • 创建数据文件时不能指定绝对路径。

    • 除非每个数据节点都有其自己的数据目录,否则无法在数据节点文件系统目录外创建表空间数据文件。

    • 如果每个数据节点都有其自己的数据目录,则可以在该目录内的任何位置创建数据文件。

    • 如果每个数据节点都有其自己的数据目录,也可以使用相对路径在该目录外创建数据文件,只要该路径在每个数据节点的主机文件系统上解析为唯一的位置。

  • FILE_BLOCK_SIZE:这是 InnoDB 通用表空间的特定选项,NDB 将其忽略。它定义了表空间数据文件的块大小。值可以以字节或千字节指定。例如,8 千字节文件块大小可以指定为 8192 或 8K。如果您不指定此选项,FILE_BLOCK_SIZE 将默认为 innodb_page_size 值。FILE_BLOCK_SIZE 在创建表空间时是必需的,以便存储压缩的 InnoDB 表 (ROW_FORMAT=COMPRESSED)。

    如果 FILE_BLOCK_SIZE 等于 innodb_page_size 值,则表空间只能包含未压缩的行格式 (COMPACTREDUNDANTDYNAMIC) 的表。压缩表的物理页大小不同于未压缩表的物理页大小。因此,压缩表不能与未压缩表共存于同一个表空间中。

    对于通用表空间包含压缩表,必须指定FILE_BLOCK_SIZE,且FILE_BLOCK_SIZE值必须是与innodb_page_size值相关的有效压缩页大小。此外,压缩表的物理页大小(KEY_BLOCK_SIZE)必须等于FILE_BLOCK_SIZE/1024。例如,如果innodb_page_size=16K,且FILE_BLOCK_SIZE=8K,则表的KEY_BLOCK_SIZE必须为8。有关更多信息,请参阅第 17.6.3.3 节,“通用表空间”

  • USE LOGFILE GROUP:对于NDB,这是之前使用CREATE LOGFILE GROUP创建的日志文件组的名称。不支持InnoDB,其中将出现错误。

  • EXTENT_SIZE:这是 NDB 特有的选项,不支持 InnoDB,哪里将出现错误。EXTENT_SIZE 设置文件所属表空间中使用的 extent 大小,以字节为单位。默认值为 1M。最小大小为 32K,理论最大值为 2G,尽管实际最大值取决于多种因素。在大多数情况下,改变 extent 大小对性能没有可测量的影响,默认值对大多数情况都是推荐的。

    一个extent是磁盘空间分配的单位。一个 extent 被填充到其容量所允许的最大程度,然后使用另一个 extent。在理论上,每个数据文件最多可以使用 65,535(64K)个 extent;然而,推荐的最大值为 32,768(32K)。单个数据文件的推荐最大大小为 32G,即 32K 个 extent × 1 MB 每个 extent。此外,一旦 extent 被分配给某个分区,就不能用于存储来自其他分区的数据;一个 extent 不能存储来自多个分区的数据。这意味着,例如,具有单个数据文件的表空间,其 INITIAL_SIZE(在下一项中描述)为 256 MB,EXTENT_SIZE 为 128M,只有两个 extent,因此只能用于存储来自最多两个不同的磁盘数据表分区的数据。

    您可以通过查询信息模式 FILES 表来查看给定数据文件中剩余的 extent 数量,从而推断文件中剩余的空间大小。有关更多讨论和示例,请参阅第 28.3.15 节,“信息模式 FILES 表”

  • 初始大小: 这个选项特定于 NDB, 并且不支持 InnoDB, 在那里它会报错。

    初始大小 参数设置使用 ADD DATAFILE 指定的数据文件的总大小(以字节为单位)。一旦创建了这个文件,其大小就不能更改;但是,您可以使用 ALTER TABLESPACE ... ADD DATAFILE 添加更多数据文件到表空间中。

    初始大小 是可选的;其默认值为 134217728(128 MB)。

    在 32 位系统上,初始大小 的最大支持值为 4294967296(4 GB)。

  • AUTOEXTEND_SIZE: 定义了当表空间满时 InnoDB 扩展表空间的大小。该设置必须是 4MB 的倍数。默认设置为 0,这将导致表空间根据隐式默认行为扩展。有关更多信息,请参阅 第 17.6.3.9 节,“表空间 AUTOEXTEND_SIZE 配置”

    在 MySQL NDB Cluster 的任何版本中都没有效果,不管使用什么存储引擎。

  • MAX_SIZE: 目前被 MySQL 忽视;保留供可能的未来使用。在 MySQL 或 MySQL NDB Cluster 的任何版本中都没有效果,不管使用什么存储引擎。

  • NODEGROUP: 目前被 MySQL 忽视;保留供可能的未来使用。在 MySQL 或 MySQL NDB Cluster 的任何版本中都没有效果,不管使用什么存储引擎。

  • WAIT: 目前被 MySQL 忽视;保留供可能的未来使用。在 MySQL 或 MySQL NDB Cluster 的任何版本中都没有效果,不管使用什么存储引擎。

  • COMMENT: 目前被 MySQL 忽视;保留供可能的未来使用。在 MySQL 或 MySQL NDB Cluster 的任何版本中都没有效果,不管使用什么存储引擎。

  • ENCRYPTION 子句启用或禁用 InnoDB 通用表空间的页面级数据加密。

    如果未指定 ENCRYPTION 子句,则 default_table_encryption 设置控制是否启用加密。ENCRYPTION 子句覆盖 default_table_encryption 设置。然而,如果启用了 table_encryption_privilege_check 变量,则需要 TABLE_ENCRYPTION_ADMIN 权限来使用与 default_table_encryption 设置不同的 ENCRYPTION 子句设置。

    在创建加密的表空间之前,必须安装并配置密钥环插件。

    当一个通用表空间被加密时,驻留在该表空间中的所有表都将被加密。同样,在加密的表空间中创建的表也将被加密。

    有关更多信息,请参阅 第 17.13 节,“InnoDB 静态加密”

  • ENGINE:定义表空间使用的存储引擎,其中 engine_name 是存储引擎的名称。目前,只有 InnoDB 存储引擎被标准 MySQL 8.3 版本支持。MySQL NDB Cluster 支持 NDBInnoDB 表空间。如果未指定该选项,则使用 default_storage_engine 系统变量的值。

  • ENGINE_ATTRIBUTE 选项用于指定主要存储引擎的表空间属性。该选项保留供将来使用。

    允许的值是一个包含有效 JSON 文档的字符串文字或空字符串 ('')。无效的 JSON 将被拒绝。

    CREATE TABLESPACE ts1 ENGINE_ATTRIBUTE='{"key":"value"}';

    ENGINE_ATTRIBUTE 值可以重复指定,而不会出错。在这种情况下,将使用最后指定的值。

    ENGINE_ATTRIBUTE 值不会被服务器检查,也不会在更改表的存储引擎时被清除。

注意事项

  • 有关 MySQL 表空间命名规则,请参阅 第 11.2 节,“模式对象名称”。除了这些规则外,斜杠字符 (/) 不允许使用,也不能使用以 innodb_ 开头的名称,因为该前缀保留供系统使用。

  • 临时通用表空间的创建不受支持。

  • 通用表空间不支持临时表。

  • 可以使用 TABLESPACE 选项与 CREATE TABLEALTER TABLE 将 InnoDB 表分区或子分区分配给文件每个表表空间。所有分区必须属于同一个存储引擎。将表分区分配给共享 InnoDB 表空间不受支持。共享表空间包括 InnoDB 系统表空间和通用表空间。

  • 通用表空间支持使用 CREATE TABLE ... TABLESPACE 添加任何行格式的表。 innodb_file_per_table 不需要启用。

  • innodb_strict_mode 不适用于通用表空间。表空间管理规则独立于 innodb_strict_mode 强制执行。如果 CREATE TABLESPACE 参数不正确或不兼容,操作将失败,不管 innodb_strict_mode 设置如何。当使用 CREATE TABLE ... TABLESPACEALTER TABLE ... TABLESPACE 将表添加到通用表空间时,innodb_strict_mode 将被忽略,但语句将被评估为 innodb_strict_mode 已启用。

  • 使用 DROP TABLESPACE 删除表空间。在删除表空间之前,必须使用 DROP TABLE 删除表空间中的所有表。删除 NDB Cluster 表空间之前,还必须使用一个或多个 ALTER TABLESPACE ... DROP DATAFILE 语句删除其数据文件。请参阅 第 25.6.11.1 节,“NDB Cluster 磁盘数据对象”

  • 所有添加到通用表空间的 InnoDB 表,包括索引和 BLOB 页都驻留在通用表空间中。

    对于分配给表空间的 NDB 表,只有未索引的列被存储在磁盘上,并实际使用表空间数据文件。所有 NDB 表的索引和索引列始终保留在内存中。

  • 类似于系统表空间,截断或删除存储在通用表空间中的表创建了通用表空间 .ibd 数据文件 中的空闲空间,该空间只能用于新的 InnoDB 数据。空间不会被释放回操作系统,因为它是为文件每个表表空间。

  • 通用表空间不与任何数据库或模式关联。

  • ALTER TABLE ... DISCARD TABLESPACEALTER TABLE ...IMPORT TABLESPACE 不支持属于通用表空间的表。

  • 服务器使用表空间级元数据锁定来锁定DDL,引用通用表空间。相比之下,服务器使用表级元数据锁定来锁定DDL,引用文件每个表表空间。

  • 生成或现有的表空间不能更改为通用表空间。

  • 通用表空间名称和文件每个表表空间名称之间没有冲突。“/”字符,该字符存在于文件每个表表空间名称中,不允许在通用表空间名称中。

  • mysqldumpmysqlpump 不转储 InnoDB CREATE TABLESPACE 语句。

InnoDB 示例

这个示例演示如何创建通用表空间并添加三个不同行格式的未压缩表。

mysql> CREATE TABLESPACE `ts1` ADD DATAFILE 'ts1.ibd' ENGINE=INNODB;

mysql> CREATE TABLE t1 (c1 INT PRIMARY KEY) TABLESPACE ts1 ROW_FORMAT=REDUNDANT;

mysql> CREATE TABLE t2 (c1 INT PRIMARY KEY) TABLESPACE ts1 ROW_FORMAT=COMPACT;

mysql> CREATE TABLE t3 (c1 INT PRIMARY KEY) TABLESPACE ts1 ROW_FORMAT=DYNAMIC;

这个示例演示如何创建通用表空间并添加一个压缩表。该示例假设默认的 innodb_page_size 值为 16K。 FILE_BLOCK_SIZE 的 8192 需要压缩表具有 8 的 KEY_BLOCK_SIZE。

mysql> CREATE TABLESPACE `ts2` ADD DATAFILE 'ts2.ibd' FILE_BLOCK_SIZE = 8192 Engine=InnoDB;

mysql> CREATE TABLE t4 (c1 INT PRIMARY KEY) TABLESPACE ts2 ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=8;

这个示例演示如何创建通用表空间,而不指定可选的 ADD DATAFILE 子句:

mysql> CREATE TABLESPACE `ts3` ENGINE=INNODB;

这个示例演示了创建撤销表空间:

mysql> CREATE UNDO TABLESPACE undo_003 ADD DATAFILE 'undo_003.ibu';

NDB 示例

假设您想创建一个名为 myts 的 NDB 集群磁盘数据表空间,使用名为 mydata-1.dat 的数据文件。一个 NDB 表空间总是需要使用一个日志文件组,包括一个或多个撤销日志文件。在这个示例中,我们首先创建一个名为 mylg 的日志文件组,包含一个名为 myundo-1.dat 的撤销日志文件,使用 CREATE LOGFILE GROUP 语句,如下所示:

mysql> CREATE LOGFILE GROUP myg1
    ->     ADD UNDOFILE 'myundo-1.dat'
    ->     ENGINE=NDB;
Query OK, 0 rows affected (3.29 sec)

现在您可以使用以下语句创建之前描述的表空间:

mysql> CREATE TABLESPACE myts
    ->     ADD DATAFILE 'mydata-1.dat'
    ->     USE LOGFILE GROUP mylg
    ->     ENGINE=NDB;
Query OK, 0 rows affected (2.98 sec)

现在您可以使用 CREATE TABLE 语句和 TABLESPACESTORAGE DISK 选项,类似于以下所示:

mysql> CREATE TABLE mytable (
    ->     id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
    ->     lname VARCHAR(50) NOT NULL,
    ->     fname VARCHAR(50) NOT NULL,
    ->     dob DATE NOT NULL,
    ->     joined DATE NOT NULL,
    ->     INDEX(last_name, first_name)
    -> )
    ->     TABLESPACE myts STORAGE DISK
    ->     ENGINE=NDB;
Query OK, 0 rows affected (1.41 sec)

需要注意的是,只有 dobjoined 列从 mytable 实际上存储在磁盘上,因为 idlnamefname 列都是索引的。

如前所述,当 CREATE TABLESPACEENGINE [=] NDB 一起使用时,在每个 NDB 集群数据节点上都会创建一个表空间和关联的数据文件。您可以通过查询 Information Schema FILES 表来验证数据文件是否创建并获取关于它们的信息,如下所示:

mysql> SELECT FILE_NAME, FILE_TYPE, LOGFILE_GROUP_NAME, STATUS, EXTRA
    ->     FROM INFORMATION_SCHEMA.FILES
    ->     WHERE TABLESPACE_NAME = 'myts';

+--------------+------------+--------------------+--------+----------------+
| file_name    | file_type  | logfile_group_name | status | extra          |
+--------------+------------+--------------------+--------+----------------+
| mydata-1.dat | DATAFILE   | mylg               | NORMAL | CLUSTER_NODE=5 |
| mydata-1.dat | DATAFILE   | mylg               | NORMAL | CLUSTER_NODE=6 |
| NULL         | TABLESPACE | mylg               | NORMAL | NULL           |
+--------------+------------+--------------------+--------+----------------+
3 rows in set (0.01 sec)

有关更多信息和示例,请参阅 第 25.6.11.1 节,“NDB 集群磁盘数据对象”