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;
ADD DATAFILE take or leave clause 是可选的。如果在创建表空间时没有指定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)。
Adding 表 to a General 表空间
创建一个通用表空间后,可以使用CREATE TABLE或ALTER TABLE语句将表添加到表空间中,以下是示例:
mysql> CREATE TABLE t1 (c1 INT PRIMARY KEY) TABLESPACE ts1;
mysql> ALTER TABLE t2 TABLESPACE ts1;
将表分区添加到共享表空间中不受支持。共享表空间包括InnoDB系统表空间和通用表空间。
详细语法信息,请见CREATE TABLE和ALTER TABLE。
通用表space 行格式支持
通用表空间支持所有表行格式(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值也可以以字节为单位指定。要确定给定FILE_BLOCK_SIZE的有效KEY_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。8192的FILE_BLOCK_SIZE要求压缩表的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移动表 Between 表spaces
ALTER TABLE语句的TABLESPACE选项可以用来将表移动到现有的通用表空间、新的文件-每-表表空间或系统表空间。
不能在共享表空间中添加表分区。共享表空间包括InnoDB系统表空间和通用表空间。
要将表从文件-每-表表空间或系统表空间移动到通用表空间,请指定通用表空间的名称。通用表空间必须存在。请参阅ALTER TABLESPACE以获取更多信息。
ALTER TABLE tbl_name TABLESPACE [=] tablespace_name;
要将表从通用表空间或文件-每-表表空间移动到系统表空间,请指定innodb_system作为表空间名称。
ALTER TABLE tbl_name TABLESPACE [=] innodb_system;
要将表从系统表空间或一般表空间移动到文件-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选项组合使用。指定在DATA DIRECTORY子句中的目录必须是InnoDB所知的。更多信息,请见Using the DATA DIRECTORY Clause。
当移动表从加密表空间时,存在限制。请见Encryption Limitations。
重命名一般表空间
使用ALTER TABLESPACE ... RENAME TO语法支持重命名一般表空间。
ALTER TABLESPACE s1 RENAME TO s2;
需要CREATE TABLESPACE权限来重命名一般表空间。
RENAME TO 操作无论autocommit设置如何都会隐式地在autocommit模式下执行。
不能在LOCK TABLES或FLUSH TABLES WITH READ LOCK对表进行操作,以便在表空间中进行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时。必须使用DROP TABLESPACE 语句来删除表空间。tablespace_名
一般的表空间不属于任何特定的数据库。DROP DATABASE操作可以删除该表空间中的表,但不能删除表空间,即使DROP DATABASE操作删除了该表空间中的所有表。
类似于系统表空间, truncating 或 dropping 该表空间中的表将在一般表空间的.ibd 数据文件中创建自由空间,这些空间只能用于新的 InnoDB 数据。空间不会被释放回操作系统,因为在DROP TABLE操作中删除文件表空间时会释放空间。
这个示例演示了如何删除 InnoDB 一般表空间。一般表空间 ts1 创建了一个单独的表。该表必须被drop在drop表空间之前。
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_名
一般表空间 限制
-
不能将生成或现有表空间更改为一般表空间。
-
创建临时的一般表空间不受支持。
-
一般表空间不支持临时表。
-
类似于系统表空间, truncating 或 dropping 在一般表空间中的表将在该表空间的.ibd 数据文件中创建自由空间,这些空间只能用于新的
InnoDB数据。空间不会被释放回操作系统,因为它在file-per-table表空间中。此外,对于位于共享表空间(一般表空间或系统表空间)中的表执行表复制
ALTER TABLE操作可能会增加表空间的使用空间。这些操作需要额外的空间,等于表中的数据加上索引。用于表复制ALTER TABLE操作所需的额外空间不会被释放回操作系统,因为它在file-per-table表空间中。 -
ALTER TABLE ... DISCARD TABLESPACE和ALTER TABLE ... IMPORT TABLESPACE对属于一般表空间的表不受支持。 -
将表分区置于一般表空间中不受支持。
-
在同一主机上运行的源服务器和副本服务器中,
ADD DATAFILE子句不受支持,因为它将导致源服务器和副本服务器在相同位置创建同名表空间,这是不允许的。然而,如果省略了ADD DATAFILE子句,表空间将在数据目录中以唯一生成的文件名称创建,这是被允许的。 -
一般表空间不能在回滚表空间目录(
innodb_undo_directory)中创建,除非该目录是InnoDB所知的。已知目录是由datadir、innodb_data_home_dir和innodb_directories变量定义的。