通用表空间是使用 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;
ENGINE = InnoDB
子句必须作为CREATE TABLESPACE
语句的一部分定义,或者InnoDB
必须被定义为默认存储引擎(default_storage_engine=InnoDB
)。
创建通用表空间后,可以使用CREATE TABLE
或tbl_name
... TABLESPACE [=] tablespace_name
ALTER TABLE
语句将表添加到表空间,如下面的示例所示:tbl_name
TABLESPACE [=] tablespace_name
mysql> CREATE TABLE t1 (c1 INT PRIMARY KEY) TABLESPACE ts1;
mysql> ALTER TABLE t2 TABLESPACE ts1;
不支持将表分区添加到共享表空间中。共享表空间包括InnoDB
系统表空间和通用表空间。
有关详细语法信息,请参阅CREATE TABLE
和ALTER 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=16KB
且FILE_BLOCK_SIZE=8K
,则压缩表的KEY_BLOCK_SIZE
必须为8。
以下表显示了允许的innodb_page_size
、FILE_BLOCK_SIZE
和KEY_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
语句的 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 TABLES
或 FLUSH 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;
是 MySQL 中的一个大小写敏感标识符。tablespace_name
-
不能将生成或现有的表空间更改为通用表空间。
-
不支持创建临时通用表空间。
-
通用表空间不支持临时表。
-
类似于系统表空间,在通用表空间中截断或删除表时,会在通用表空间的 .ibd 数据文件 中创建免费空间,该空间只能用于新的
InnoDB
数据。空间不会被释放回操作系统,就像在 文件每个表 表空间中那样。此外,在共享表空间(通用表空间或系统表空间)中驻留的表上的表复制
ALTER TABLE
操作将增加表空间使用的空间量。这些操作需要与表中的数据和索引一样多的额外空间。表复制ALTER TABLE
操作所需的额外空间不会被释放回操作系统,因为它是为文件每个表表空间。 -
ALTER TABLE ... DISCARD TABLESPACE
和ALTER TABLE ...IMPORT TABLESPACE
不支持属于通用表空间的表。 -
将表分区放在通用表空间中是不支持的。
-
在源和副本驻留在同一主机的复制环境中,不支持ADD DATAFILE子句,因为这将导致源和副本在同一位置创建同名的表空间,这是不支持的。然而,如果省略ADD DATAFILE子句,表空间将在数据目录中创建,具有唯一的生成文件名,这是允许的。
-
通用表空间不能在undo表空间目录(
innodb_undo_directory
)中创建,除非该目录是InnoDB
已知的。已知目录是由datadir
、innodb_data_home_dir
和innodb_directories
变量定义的。