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

17.6.3.3 通用表空间

通用表空间是使用 CREATE TABLESPACE 语法创建的共享 InnoDB 表空间。通用表空间的功能和特性在本节的以下主题中描述:

通用表空间功能

通用表空间提供以下功能:

  • 与系统表空间类似,通用表空间是共享表空间,可以存储多个表的数据。

  • 通用表空间相比文件每表表空间具有潜在的内存优势。服务器在表空间的生命周期内保留表空间元数据。在较少的通用表空间中存储多个表的数据将消耗较少的内存用于表空间元数据,而不是在每个表的文件每表表空间中存储数据。

  • 通用表空间数据文件可以放在 MySQL 数据目录相对或独立的目录中,这提供了与文件每表表空间类似的数据文件和存储管理功能。与文件每表表空间一样,将数据文件放在 MySQL 数据目录外部允许您单独管理关键表的性能,设置 RAID 或 DRBD 对特定表,或者将表绑定到特定磁盘等。

  • 通用表空间支持所有表行格式和相关功能。

  • 可以使用 TABLESPACE 选项与 CREATE TABLE 在通用表空间、文件每表表空间或系统表空间中创建表。

  • 可以使用 TABLESPACE 选项与 ALTER TABLE 将表移到通用表空间、文件每表表空间和系统表空间之间。

创建通用表空间

通用表空间使用 CREATE TABLESPACE 语法创建。

CREATE TABLESPACE tablespace_name
    [ADD DATAFILE 'file_name']
    [FILE_BLOCK_SIZE = value]
        [ENGINE [=] engine_name]

通用表空间可以在数据目录或其外部创建。为了避免与隐式创建的文件每表表空间冲突,不支持在数据目录下的子目录中创建通用表空间。当在数据目录外部创建通用表空间时,目录必须存在并且在创建表空间之前必须已知于 InnoDB。要使未知目录已知于 InnoDB,请将目录添加到 innodb_directories 参数值中。innodb_directories 是一个只读启动选项。配置它需要重新启动服务器。

示例:

在数据目录中创建通用表空间:

mysql> CREATE TABLESPACE `ts1` ADD DATAFILE 'ts1.ibd' Engine=InnoDB;

or

mysql> CREATE TABLESPACE `ts1` Engine=InnoDB;

添加数据文件子句是可选的。如果在创建表空间时没有指定添加数据文件子句,则会隐式创建一个具有唯一文件名的表空间数据文件。该唯一文件名是一个128位UUID,格式化为五组用破折号分隔的十六进制数字(aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee)。通用表空间数据文件包括一个.ibd文件扩展名。在复制环境中,源服务器上创建的数据文件名与副本服务器上创建的数据文件名不同。

在数据目录外创建通用表空间:

mysql> CREATE TABLESPACE `ts1` ADD DATAFILE '/my/tablespace/directory/ts1.ibd' Engine=InnoDB;

您可以指定一个相对于数据目录的路径,只要表空间目录不在数据目录下。在这个示例中,my_tablespace目录位于数据目录的同一级别:

mysql> CREATE TABLESPACE `ts1` ADD DATAFILE '../my_tablespace/ts1.ibd' Engine=InnoDB;
Note

ENGINE = InnoDB子句必须作为CREATE TABLESPACE语句的一部分定义,或者InnoDB必须被定义为默认存储引擎(default_storage_engine=InnoDB)。

将表添加到通用表空间

创建通用表空间后,可以使用CREATE TABLE tbl_name ... TABLESPACE [=] tablespace_nameALTER TABLE tbl_name TABLESPACE [=] tablespace_name语句将表添加到表空间,如下面的示例所示:

CREATE TABLE

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

ALTER TABLE

mysql> ALTER TABLE t2 TABLESPACE ts1;

不支持将表分区添加到共享表空间中。共享表空间包括InnoDB系统表空间和通用表空间。

有关详细语法信息,请参阅CREATE TABLEALTER TABLE

通用表空间行格式支持

通用表空间支持所有表行格式(REDUNDANTCOMPACTDYNAMICCOMPRESSED),但压缩表和未压缩表不能在同一个通用表空间中共存,因为它们的物理页大小不同。

要在通用表空间中包含压缩表(ROW_FORMAT=COMPRESSED),必须指定FILE_BLOCK_SIZE选项,并且FILE_BLOCK_SIZE值必须是有效的压缩页大小,相对于innodb_page_size值。另外,压缩表的物理页大小(KEY_BLOCK_SIZE)必须等于FILE_BLOCK_SIZE/1024。例如,如果innodb_page_size=16KBFILE_BLOCK_SIZE=8K,则压缩表的KEY_BLOCK_SIZE必须为8。

以下表显示了允许的innodb_page_sizeFILE_BLOCK_SIZEKEY_BLOCK_SIZE组合。FILE_BLOCK_SIZE值也可以以字节为单位指定。要确定有效的KEY_BLOCK_SIZE值,请将FILE_BLOCK_SIZE值除以1024。表压缩不支持32K和64KInnoDB页大小。有关KEY_BLOCK_SIZE的更多信息,请参阅CREATE TABLE第17.9.1.2节“创建压缩表”

表 17.3 压缩表的允许页面大小、FILE_BLOCK_SIZE 和 KEY_BLOCK_SIZE 组合

InnoDB Page Size (innodb_page_size) Permitted FILE_BLOCK_SIZE Value Permitted KEY_BLOCK_SIZE Value
64KB 64K (65536) 不支持压缩
32KB 32K (32768) 不支持压缩
16KB 16K (16384) 无。如果 innodb_page_size 等于 FILE_BLOCK_SIZE,则表空间不能包含压缩表。
16KB 8K (8192) 8
16KB 4K (4096) 4
16KB 2K (2048) 2
16KB 1K (1024) 1
8KB 8K (8192) 无。如果 innodb_page_size 等于 FILE_BLOCK_SIZE,则表空间不能包含压缩表。
8KB 4K (4096) 4
8KB 2K (2048) 2
8KB 1K (1024) 1
4KB 4K (4096) 无。如果 innodb_page_size 等于 FILE_BLOCK_SIZE,则表空间不能包含压缩表。
4KB 2K (2048) 2
4KB 1K (1024) 1

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

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;

如果您在创建通用表空间时不指定 FILE_BLOCK_SIZE,则 FILE_BLOCK_SIZE 将默认为 innodb_page_size。当 FILE_BLOCK_SIZE 等于 innodb_page_size 时,表空间只能包含未压缩的表(COMPACT、REDUNDANT 和 DYNAMIC 行格式)。

使用 ALTER TABLE 将表移到表空间

ALTER TABLE 语句的 TABLESPACE 选项可以将表移到现有的通用表空间、新的文件每表表空间或系统表空间。

不支持将表分区添加到共享表空间中。共享表空间包括 InnoDB 系统表空间和通用表空间。

要将表从文件每表表空间或系统表空间移到通用表空间,请指定通用表空间的名称。通用表空间必须存在。请参阅 ALTER TABLESPACE 以获取更多信息。

ALTER TABLE tbl_name TABLESPACE [=] tablespace_name;

要将表从通用表空间或文件每表表空间移到系统表空间,请指定 innodb_system 作为表空间名称。

ALTER TABLE tbl_name TABLESPACE [=] innodb_system;

要将表从系统表空间或通用表空间移到文件每表表空间,请指定 innodb_file_per_table 作为表空间名称。

ALTER TABLE tbl_name TABLESPACE [=] innodb_file_per_table;

ALTER TABLE ... TABLESPACE 操作会导致整个表的重建,即使 TABLESPACE 属性没有从其之前的值更改。

ALTER TABLE ... TABLESPACE 语法不支持将表从临时表空间移到持久表空间。

DATA DIRECTORY 子句仅与 CREATE TABLE ... TABLESPACE=innodb_file_per_table 一起使用,但否则不支持与 TABLESPACE 选项结合使用。DATA DIRECTORY 子句中指定的目录必须是 InnoDB 已知的目录。有关更多信息,请参阅 使用 DATA DIRECTORY 子句

移动加密表空间中的表时存在限制。请参阅 加密限制

重命名通用表空间

使用 ALTER TABLESPACE ... RENAME TO 语法支持重命名通用表空间。

ALTER TABLESPACE s1 RENAME TO s2;

重命名通用表空间需要 CREATE TABLESPACE 权限。

RENAME TO 操作隐式地在 autocommit 模式下执行,不管 autocommit 设置如何。

不能在 LOCK TABLESFLUSH TABLES WITH READ LOCK 生效时对表空间进行 RENAME TO 操作。

在重命名通用表空间时,会在表空间中的表上获取独占的 metadata 锁,以防止并发 DDL。支持并发 DML。

删除通用表空间

使用 DROP TABLESPACE 语句删除 InnoDB 通用表空间。

在删除表空间之前,必须从表空间中删除所有表。如果表空间不为空,DROP TABLESPACE 将返回错误。

使用类似以下查询来标识通用表空间中的表。

mysql> SELECT a.NAME AS space_name, b.NAME AS table_name FROM INFORMATION_SCHEMA.INNODB_TABLESPACES a,
       INFORMATION_SCHEMA.INNODB_TABLES b WHERE a.SPACE=b.SPACE AND a.NAME LIKE 'ts1';
+------------+------------+
| space_name | table_name |
+------------+------------+
| ts1        | test/t1    |
| ts1        | test/t2    |
| ts1        | test/t3    |
+------------+------------+

通用 InnoDB 表空间不会在最后一个表被删除时自动删除。必须使用 DROP TABLESPACE tablespace_name 显式删除表空间。

通用表空间不属于任何特定的数据库。DROP DATABASE 操作可以删除属于通用表空间的表,但不能删除表空间,即使 DROP DATABASE 操作删除了表空间中的所有表。

类似于系统表空间,在通用表空间中截断或删除表时,会在通用表空间的 .ibd 数据文件 中创建免费空间,该空间只能用于新的 InnoDB 数据。空间不会被释放回操作系统,就像在 DROP TABLE 操作中那样。

以下示例演示如何删除 InnoDB 通用表空间。首先创建一个名为 ts1 的通用表空间,然后删除该表空间中的表,最后删除表空间。

mysql> CREATE TABLESPACE `ts1` ADD DATAFILE 'ts1.ibd' Engine=InnoDB;

mysql> CREATE TABLE t1 (c1 INT PRIMARY KEY) TABLESPACE ts1 Engine=InnoDB;

mysql> DROP TABLE t1;

mysql> DROP TABLESPACE ts1;
Note

tablespace_name 是 MySQL 中的一个大小写敏感标识符。

通用表空间限制