Documentation Home

15.6.3.3 通用表空间

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

通用表空间功能

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

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

  • 与file-per-table 表空间 相比,通用表空间具有潜在的内存优势 。服务器在表空间的生命周期内将表空间元数据保存在内存中。更少的通用表空间中的多个表比单独的每个表文件表空间中的相同数量的表消耗更少的表空间元数据内存。

  • 通用表空间数据文件可以放在相对于或独立于MySQL数据目录的目录中,这为您提供了 file-per-table表空间的许多数据文件和存储管理功能。与 file-per-table 表空间一样,将数据文件放置在 MySQL 数据目录之外的能力允许您单独管理关键表的性能,为特定表设置 RAID 或 DRBD,或者将表绑定到特定磁盘,例如。

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

  • TABLESPACE选项可用于 CREATE TABLE在通用表空间、file-per-table 表空间或系统表空间中创建表。

  • TABLESPACE选项可用于 ALTER TABLE在通用表空间、file-per-table 表空间和系统表空间之间移动表。

创建通用表空间

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

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

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

例子:

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

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

或者

mysql> CREATE TABLESPACE `ts1` Engine=InnoDB;

从 MySQL 8.0.14 开始,该ADD DATAFILE子句是可选的,在此之前是必需的。如果ADD DATAFILE在创建表空间时没有指定该子句,则隐式创建一个具有唯一文件名的表空间数据文件。唯一的文件名是一个 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;
笔记

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

将表添加到通用表空间

创建通用表空间后, 可以使用or 语句向表空间中添加表,示例如下: 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;
笔记

在 MySQL 5.7.24 中弃用了对向共享表空间添加表分区的支持,并在 MySQL 8.0.13 中将其删除。共享表空间包括InnoDB系统表空间和通用表空间。

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

通用表空间行格式支持

通用表空间支持所有表行格式(REDUNDANT, COMPACT, DYNAMIC, COMPRESSED),但需要注意的是,由于物理页面大小不同,压缩表和未压缩表不能共存于同一通用表空间中。

对于包含压缩表 ( 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=8KKEY_BLOCK_SIZE则表的 必须为 8。

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

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

InnoDB 页面大小 (innodb_page_size) 允许的 FILE_BLOCK_SIZE 值 允许的 KEY_BLOCK_SIZE 值
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。8192的 FILE_BLOCK_SIZE要求压缩表的 aKEY_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,表空间可能只包含具有未压缩行格式(COMPACTREDUNDANTDYNAMIC行格式)的表。

使用 ALTER TABLE 在表空间之间移动表

ALTER TABLEwith TABLESPACE选项可用于将表移动到现有的通用表空间、新的 file-per-table 表空间或系统表空间。

笔记

在 MySQL 5.7.24 中弃用了对在共享表空间中放置表分区的支持,并删除了 MySQL 8.0.13。共享表空间包括InnoDB系统表空间和通用表空间。

要将表从 file-per-table 表空间或从系统表空间移动到通用表空间,请指定通用表空间的名称。通用表空间必须存在。有关 ALTER TABLESPACE详细信息,请参阅。

ALTER TABLE tbl_name TABLESPACE [=] tablespace_name;

要将表从通用表空间或 file-per-table 表空间移动到系统表空间,请指定 innodb_system为表空间名称。

ALTER TABLE tbl_name TABLESPACE [=] innodb_system;

要将表从系统表空间或通用表空间移动到 file-per-table 表空间,请指定 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选项结合使用。从 MySQL 8.0.21 开始,子句中指定的目录DATA DIRECTORY 必须为InnoDB. 有关详细信息,请参阅 使用 DATA DIRECTORY 子句

从加密表空间移动表时有限制。请参阅 加密限制

重命名通用表空间

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

ALTER TABLESPACE s1 RENAME TO s2;

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

RENAME TOautocommit无论设置如何,操作都在模式下隐式执行autocommit

对于驻留在表空间中的表, RENAME TO无法执行操作LOCK TABLES或 对表有效。FLUSH TABLES WITH READ LOCK

在重命名表空间时,在通用表空间内的表上采用 独占元数据锁,这可以防止并发 DDL。支持并发 DML。

删除通用表空间

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

在操作之前必须从表空间中删除所有表 DROP TABLESPACE。如果表空间不为空,则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数据的可用空间。空间不会像在操作期间删除 file-per-table 表空间时那样释放回操作系统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;
笔记

tablespace_name 是 MySQL 中区分大小写的标识符。

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

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

  • 一般表空间不支持临时表。

  • 与系统表空间类似,截断或删除存储在通用表空间中的表会在通用表空间 .ibd 数据文件内部创建只能用于新InnoDB数据的可用空间。空间不会像file-per-table表空间那样释放回操作系统 。

    ALTER TABLE此外,对驻留在共享表空间(通用表空间或系统表空间)中的表进行 表复制操作会增加表空间使用的空间量。此类操作需要与表中的数据加上索引一样多的额外空间。表复制操作所需的额外空间ALTER TABLE 不会像每个表的文件表空间那样释放回操作系统。

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

  • 在 MySQL 5.7.24 中弃用了对在通用表空间中放置表分区的支持,并在 MySQL 8.0.13 中删除了。

  • 在源和副本位于同一主机上的复制环境中不支持该ADD DATAFILE子句,因为它会导致源和副本在同一位置创建同名的表空间,这是不受支持的。但是,如果 ADD DATAFILE省略该子句,则在数据目录中创建表空间,生成的文件名是唯一的,这是允许的。

  • 从 MySQL 8.0.21 开始,不能在撤消表空间目录 ( innodb_undo_directory) 中创建通用表空间,除非直接知道InnoDB。已知目录是由 datadirinnodb_data_home_dirinnodb_directories 变量定义的目录。