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']
这个语句用于创建表空间。语法和 semantics 取决于所使用的存储引擎。在标准 MySQL 发行版中,这总是InnoDB
表空间。MySQL NDB 集群也支持使用NDB
存储引擎的表空间。
CREATE TABLESPACE
语句用于创建一般表空间或回滚表空间。必须指定UNDO
关键字来创建回滚表空间。
一个一般表空间是一个共享表空间。它可以持有多个表,并支持所有表行格式。一般表空间可以在数据目录相对位置或独立位置创建。
创建了一个InnoDB
通用表空间后,使用CREATE TABLE
或tbl_name
... TABLESPACE [=] tablespace_name
ALTER TABLE
将表添加到表空间中。更多信息,请参见第17.6.3.3节,“通用表空间”。tbl_name
TABLESPACE [=] tablespace_name
回滚表空间中包含回滚日志。可以在指定完全合格的数据文件路径下创建回滚表空间。更多信息,请参见第17.6.3.4节,“回滚表空间”。
这个语句用于创建一个表空间,该表空间可以包含一个或多个数据文件,为NDB集群磁盘数据表提供存储空间(见第25.6.11节,“NDB集群磁盘数据表”)。使用这个语句创建一个数据文件,并将其添加到表空间中。可以使用ALTER TABLESPACE
语句(见第15.1.10节,“ALTER TABLESPACE 语句”)添加更多数据文件到表空间中。
所有 NDB 集群磁盘数据对象共享同一个命名空间。这意味着每个磁盘数据对象都必须唯一命名(而不是每种类型的磁盘数据对象)。例如,你不能有一个表空间和日志文件组具有相同名称,或者表空间和数据文件具有相同名称。
要创建一个或多个UNDO
日志文件组,必须使用USE LOGFILE GROUP
子句。logfile_group
必须是使用CREATE LOGFILE GROUP
(见第15.1.16节,“CREATE LOGFILE GROUP 语句”)创建的现有日志文件组。多个表空间可以使用相同的日志文件组进行UNDO
日志记录。
设置EXTENT_SIZE
或INITIAL_SIZE
时,可以选择性地在数字后添加一个字母缩写,类似于my.cnf
文件中使用的缩写。通常,这是一个字母中的M
(兆)或G
(GB)。
INITIAL_SIZE
和EXTENT_SIZE
都受以下规则的限制:
-
EXTENT_SIZE
向上四舍五入到最近的32K整数倍。 -
INITIAL_SIZE
向下四舍五入到最近的32K整数倍,然后再向上四舍五入到最近的EXTENT_SIZE
(在任何四舍五入后)
NDB
保留了表空间的4%用于数据节点重启操作。这块保留空间不能用来存储数据。
刚才描述的圆整是明确进行的,MySQL 服务器在执行任何圆整操作时都会发出警告。这些圆整值也被 NDB 内核用于计算INFORMATION_SCHEMA.FILES
列值和其他用途。但是,为了避免意外结果,我们建议总是使用32K的整数倍数来指定这些选项。
当CREATE TABLESPACE
使用 ENGINE [=] NDB
时,在每个集群数据节点上创建表空间和关联的数据文件。您可以通过查询信息_schemaFILES
表来验证数据文件是否创建并获取关于它们的信息。(见本节后面的示例。)
(见第28.3.15节,“INFORMATION_SCHEMA 文件表”。)
-
ADD DATAFILE
: 定义表空间数据文件的名称。创建NDB
表空间时,这个选项总是必需;创建InnoDB
表空间时,只有在创建回滚表空间时才需要。包括路径的
,必须用单引号或双引号括起来。文件名(不计文件扩展名)和目录名至少要有一字节长。零长度文件名和目录名不支持。file_name
由于
InnoDB
和NDB
对数据文件的处理方式有很大不同,以下讨论将单独对这两个存储引擎进行介绍。InnoDB 数据文件 。一个
InnoDB
表空间仅支持一个数据文件,该文件名必须包括.ibd
扩展名。要将
InnoDB
一般表空间数据文件放在数据目录外,包括完全限定路径或相对数据目录的路径。只有完全限定路径允许用于回滚表空间。如果不指定路径,创建一般表空间时在数据目录下。没有指定路径的回滚表空间在innodb_undo_directory
变量定义的目录下创建。如果innodb_undo_directory
未设置,回滚表空间在数据目录下创建。为了避免与隐式创建的文件表空间冲突,不能在数据目录下子目录中创建
InnoDB
一般表空间。创建一般表空间或回滚表空间时,必须存在该目录且已知给InnoDB
。要使目录被InnoDB
知道,可以将其添加到innodb_directories
值或其中之一的变量值中。innodb_directories
是只读变量。配置它需要重新启动服务器。如果在创建
InnoDB
表空间时不指定ADD DATAFILE
子句,隐式创建一个唯一文件名的表空间数据文件。唯一文件名是一个 128 位 UUID,格式为五个十六进制数字组合(aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee
)。如果存储引擎需要,可以添加文件扩展名。对InnoDB
一般表空间数据文件,添加.ibd
文件扩展名。在复制环境中,源服务器创建的数据文件名与副本服务器创建的数据文件名不同。创建
InnoDB
表空间时,ADD DATAFILE
子句不允许循环目录引用。例如,以下语句中的循环目录引用(/../
)不被允许:CREATE TABLESPACE ts1 ADD DATAFILE ts1.ibd 'any_directory/../ts1.ibd';
在 Linux 上,存在一个关于圆环目录引用限制的例外,如果前一个目录是一个符号链接。例如,上面的数据文件路径允许如果
any_directory
是一个符号链接。(它仍然允许数据文件路径以 '../
' 开头。)NDB 数据文件 一个
NDB
表空间支持多个数据文件,这些文件可以有任何合法的文件名;在创建了 NDB 集群表空间后,可以使用ALTER TABLESPACE
语句添加更多数据文件。一个
NDB
表空间数据文件默认创建在数据节点文件系统目录中—that 是,名为ndb_
的目录下,该目录位于数据节点的数据目录 (nodeid
_fs/TSDataDir
),其中nodeid
是数据节点的NodeId
。要将数据文件放在默认位置以外,包括绝对目录路径或相对于默认位置的路径。如果指定的目录不存在,NDB
尝试创建它;系统用户账户必须具有创建该目录的权限。Note当确定数据文件路径时,
NDB
不会扩展'~'
(波浪符) 字符。在同一物理主机上运行多个数据节点时,以下考虑因素适用:
-
不能指定绝对路径来创建数据文件。
-
除非每个数据节点都有单独的数据目录,否则无法在数据节点外部创建表空间数据文件。
-
如果每个数据节点都有自己的数据目录,那么可以在这个目录内随意创建数据文件。
-
如果每个数据节点都有自己的数据目录,那么也可能使用相对路径来创建数据文件,只要该路径在每个主机上的文件系统中是唯一的。
-
-
FILE_BLOCK_SIZE
:只适用于InnoDB
通用表空间,NDB
忽略该选项。该选项定义了表空间数据文件的块大小,可以指定以字节或千字节为单位。例如,8千字节的文件块大小可以指定为8192或8K。如果不指定该选项,FILE_BLOCK_SIZE
将默认使用innodb_page_size
的值。FILE_BLOCK_SIZE
在创建压缩表空间时(ROW_FORMAT=COMPRESSED
)是必需的,在这种情况下,必须在创建表空间时定义该选项。如果
FILE_BLOCK_SIZE
等于innodb_page_size
的值,那么表空间只能包含未压缩行格式的表(COMPACT
、REDUNDANT
和DYNAMIC
)。具有COMPRESSED
行格式的表的物理页大小与未压缩表不同。因此,压缩表不能在同一个表空间中与未压缩表共存。要使一般表空间包含压缩表,必须指定
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—that is,32K 个extent × 1 MB per extent。此外,一旦一个extent被分配给某个分区,就不能用于存储来自不同分区的数据;一个extent不能存储来自多个分区的数据。这意味着,例如,一个表空间拥有单个数据文件,
INITIAL_SIZE
(在以下项目中描述)为 256 MB,EXTENT_SIZE
为 128M,那么这个表空间最多只能用于存储来自两个不同的磁盘数据表分区的数据。通过查询信息架构
FILES
表,您可以看到某个数据文件中剩余的空闲空间数量,从而推断该文件中的剩余空间大小。对于更多讨论和示例,见第28.3.15节,“The INFORMATION_SCHEMA FILES 表”。 -
INITIAL_SIZE
:这是特定的NDB选项,不支持InnoDB,在其中失败。使用
INITIAL_SIZE
参数设置数据文件的总大小,该文件创建后不能改变,但是可以使用ALTER TABLESPACE ... ADD DATAFILE
添加更多数据文件到表空间。INITIAL_SIZE
是可选的,缺省值为134217728(128 MB).在32位系统上,
INITIAL_SIZE
的最大支持值为4294967296(4 GB). -
AUTOEXTEND_SIZE
:定义InnoDB
在表空间满时扩展大小的值,该设置必须是4MB的倍数。缺省设置为0,导致表空间根据隐式默认行为进行扩展。对于更多信息,见第17.6.3.9节,“Tablespace AUTOEXTEND_SIZE 配置”。在 MySQL NDB 集群的任何版本中都没有影响,不管使用哪种存储引擎。
-
MAX_SIZE
: 当前MySQL忽略,保留可能将来使用。无论是在 MySQL 或 MySQL NDB 集群的任何版本中,都不管使用哪种存储引擎都没有影响。 -
NODEGROUP
: 当前MySQL忽略,保留可能将来使用。无论是在 MySQL 或 MySQL NDB 集群的任何版本中,都不管使用哪种存储引擎都没有影响。 -
WAIT
: 当前MySQL忽略,保留可能将来使用。无论是在 MySQL 或 MySQL NDB 集群的任何版本中,都不管使用哪种存储引擎都没有影响。 -
COMMENT
: 当前MySQL忽略,保留可能将来使用。无论是在 MySQL 或 MySQL NDB 集群的任何版本中,都不管使用哪种存储引擎都没有影响。 -
ENCRYPTION
子句启用或禁用InnoDB
一般表空间的页面级数据加密。如果不指定
ENCRYPTION
子句,default_table_encryption
设置控制是否启用加密。ENCRYPTION
子句override了default_table_encryption
设置。但是,如果table_encryption_privilege_check
变量启用,需要TABLE_ENCRYPTION_ADMIN
权限来使用与default_table_encryption
设置不同的ENCRYPTION
子句设置。必须安装和配置密钥ring插件,才能创建加密表空间。
当一般表空间加密时,所有在该表空间中的表都加密。同样,创建于加密表空间的表也会加密。
-
ENGINE
: 定义使用表空间的存储引擎,engine_name
是存储引擎的名称。标准 MySQL 8.4 版本当前只支持InnoDB
存储引擎。MySQL NDB 集群同时支持NDB
和InnoDB
表空间。default_storage_engine
系统变量的值将被用于ENGINE
如果未指定该选项。 -
ENGINE_ATTRIBUTE
选项用于指定主要存储引擎的表空间属性,该选项保留供未来使用。分配给该选项的值必须是一个有效的 JSON 文档字符串或空字符串 ('')。无效的 JSON 将被拒绝。
CREATE TABLESPACE ts1 ENGINE_ATTRIBUTE='{"key":"value"}';
ENGINE_ATTRIBUTE
值可以重复没有错误。在这种情况下,最后指定的值将被使用。ENGINE_ATTRIBUTE
值不被服务器检查,也不会在更改表的存储引擎时清除。
-
关于 MySQL 表空间命名规则,见第11.2节,“Schema Object Names”。此外,还不能使用以
innodb_
开头的名称,因为该前缀保留供系统使用。 -
创建临时通用表空间不受支持。
-
通用表空间不支持临时表。
-
可以使用
TABLESPACE
选项与CREATE TABLE
或ALTER TABLE
将 InnoDB 表分区或子分区分配到文件表空间中。所有分区都必须属于同一个存储引擎。将表分区分配给共享的 InnoDB 表空间不支持,共享的表空间包括 InnoDB 系统表空间和一般表空间。 -
一般表空间支持使用
CREATE TABLE ... TABLESPACE
添加任何行格式的表。innodb_file_per_table
不需要启用。 -
innodb_strict_mode
对于一般表空间无效。表空间管理规则独立于innodb_strict_mode
,如果CREATE TABLESPACE
参数错误或不兼容,操作总是失败,不管innodb_strict_mode
设置是什么。使用CREATE TABLE ... TABLESPACE
或ALTER TABLE ... TABLESPACE
添加表到一般表空间时,innodb_strict_mode
被忽略,但语句将被评估为如果innodb_strict_mode
启用。 -
使用
DROP TABLESPACE
删除表空间。所有表必须使用DROP TABLE
在删除表空间之前删除。删除 NDB 集群表空间前,必须使用一个或多个ALTER TABLESPACE ... DROP DATATFILE
语句删除所有数据文件。见第25.6.11.1节,“NDB 集群磁盘数据对象”。 -
所有
InnoDB
表的部分都位于通用表空间中,包括索引和BLOB
页。对于分配到表空间的
NDB
表,只有未索引的列存储在磁盘上,实际使用的是表空间数据文件。所有NDB
表的索引和索引列总是保留在内存中。 -
类似于系统表空间,通用表空间中的表_TRUNCATE 或 DROP 创建了自由空间,可以用于新建
InnoDB
数据,但不能释放给操作系统,因为文件-per-表表空间可以释放。 -
通用表空间不与任何数据库或模式相关联。
-
ALTER TABLE ... DISCARD TABLESPACE
和ALTER TABLE ... IMPORT TABLESPACE
对于通用表空间中的表不支持。 -
服务器使用表空间级别元数据锁定来执行对通用表空间的 DDL 操作,相比之下,服务器使用表级别元数据锁定来执行对文件-per-表表空间的 DDL 操作。
-
不能将生成或存在的表空间更改为通用表空间。
-
一般表空间名称和文件表空间名称之间没有冲突。文件表空间名称中存在的“/”字符在一般表空间名称中不被允许。
-
mysqldump 不会dump
InnoDB
CREATE TABLESPACE
语句。
这个示例演示了创建一个一般表空间,并添加三个不同行格式的未压缩表。
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,压缩表需要的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;
这个示例演示了创建一个一般表空间,不指定可选的ADD DATAFILE
子句:
mysql> CREATE TABLESPACE `ts3` ENGINE=INNODB;
这个示例演示了创建一个undo表空间:
mysql> CREATE UNDO TABLESPACE undo_003 ADD DATAFILE 'undo_003.ibu';
假设您想创建一个名为 myts
的 NDB 集群磁盘数据表空间,使用名为 mydata-1.dat
的数据文件。一个 NDB
表空间总是需要使用一个或多个回滚日志文件组。对于这个示例,我们首先创建一个名为 mylg
的日志文件组,包含一个名为 myundo-1.dat
的回滚日志文件,使用以下语句:
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)
您现在可以使用带有 TABLESPACE
和 STORAGE DISK
选项的 CREATE TABLE
语句,类似于以下所示:
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)
需要注意的是,只有 dob
和 joined
列从 mytable
中实际存储在磁盘上,因为 id
、lname
和 fname
列都被索引了。
如前所述,使用 CREATE TABLESPACE
语句时,带有 ENGINE [=] NDB
,在每个 NDB 集群数据节点上创建表空间和关联的数据文件。您可以通过查询信息_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集群磁盘数据对象”。