通用表空间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_name
ALTER TABLE
tbl_name
TABLESPACE [=]
tablespace_name
mysql> CREATE TABLE t1 (c1 INT PRIMARY KEY) TABLESPACE ts1;
mysql> ALTER TABLE t2 TABLESPACE ts1;
在 MySQL 5.7.24 中弃用了对向共享表空间添加表分区的支持,并在 MySQL 8.0.13 中将其删除。共享表空间包括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
,请将该
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
,表空间可能只包含具有未压缩行格式(COMPACT
、
REDUNDANT
和DYNAMIC
行格式)的表。
ALTER TABLE
with
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 TO
autocommit
无论设置如何,操作都在模式下隐式执行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;
是 MySQL 中区分大小写的标识符。
tablespace_name
生成的或现有的表空间不能更改为通用表空间。
不支持创建临时通用表空间。
一般表空间不支持临时表。
与系统表空间类似,截断或删除存储在通用表空间中的表会在通用表空间 .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
。已知目录是由datadir
、innodb_data_home_dir
和innodb_directories
变量定义的目录。