• 首页
  • vue
  • TypeScript
  • JavaScript
  • scss
  • css3
  • html5
  • php
  • MySQL
  • redis
  • jQuery
  • 通用表空间

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

    • 常规表空间功能
    • 创建通用表空间
    • 将表添加到常规表空间
    • 常规表空间行格式支持
    • 使用ALTER TABLE在表空间之间移动表
    • 重命名通用表空间
    • 删除通用表空间
    • 常规表空间限制

    常规表空间功能

    常规表空间功能提供以下功能:

    • 类似于系统表空间,常规表空间是共享表空间,可以存储多个表的数据。
    • 常规表空间比每表文件表空间具有潜在的内存优势。服务器在表空间的生存期内将表空间元数据保留在内存中。与单独的每表文件表空间中的相同数量的表相比,较少的常规表空间中的多个表为表空间元数据消耗的内存更少。
    • 常规表空间数据文件可以放置在相对于MySQL数据目录或独立于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;
    

    要么

    mysql> CREATE TABLESPACE `ts1` Engine=InnoDB;
    

    ADD DATAFILEMySQL 8.0.14开始,该子句是可选的,并且在此之前是必需的。如果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)。

    将表添加到常规表空间

    创建InnoDB通用表空间之后,可以使用或将表添加到表空间,如以下示例所示: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

    常规表空间行格式支持

    一般的表空间支持所有表行格式(REDUNDANTCOMPACTDYNAMICCOMPRESSED)需要提醒的是压缩和非压缩表不能在同一个表空间一般共存由于不同的物理页面大小。

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

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

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

    InnoDB页面大小(innodb_page_size)允许的FILE_BLOCK_SIZE值允许的KEY_BLOCK_SIZE值
    64KB64K(65536)不支持压缩
    32KB32K(32768)不支持压缩
    16KB16K(16384)N / A:如果innodb_page_size等于FILE_BLOCK_SIZE,则表空间不能包含压缩表。
    16KB8K(8192)8
    16KB4K(4096)4
    16KB2K(2048)2
    16KB1K(1024)1个
    8KB8K(8192)N / A:如果innodb_page_size等于FILE_BLOCK_SIZE,则表空间不能包含压缩表。
    8KB4K(4096)4
    8KB2K(2048)2
    8KB1K(1024)1个
    4KB4K(4096)N / A:如果innodb_page_size等于FILE_BLOCK_SIZE,则表空间不能包含压缩表。
    4KB2K(2048)2
    4KB1K(1024)1个

    本示例演示如何创建常规表空间并添加压缩表。该示例假定默认innodb_page_size值为16KB。在FILE_BLOCK_SIZE8192要求压缩表有KEY_BLOCK_SIZE8个。

    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 TABLETABLESPACE选项将表移动到现有的常规表空间,新的每表文件表空间或系统表空间。

    注意

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

    要将表从每表文件表空间或系统表空间移至常规表空间,请指定常规表空间的名称。常规表空间必须存在。请参阅CREATE 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选项结合使用。

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

    重命名通用表空间

    使用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操作删除了属于该表空间的所有表,也不能删除该表空间。必须使用显式删除常规表空间。DROP TABLESPACE tablespace_name

    与系统表空间类似,截断或删除存储在常规表空间中的表会在常规表空间.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;
    
    注意

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

    常规表空间限制

    • 生成的或现有的表空间无法更改为常规表空间。
    • 不支持创建临时通用表空间。
    • 常规表空间不支持临时表。
    • 与系统表空间类似,截断或删除存储在常规表空间中的表会在常规表空间.ibd数据文件内部创建可用空间,该空间只能用于新InnoDB数据。每个表文件表空间的空间不会释放回操作系统。

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

    • ALTER TABLE ... DISCARD TABLESPACE并且ALTER TABLE ...IMPORT TABLESPACE不支持属于一般的表空间的表。
    • 在MySQL 5.7.24中已弃用了将表分区放置在常规表空间中的支持,而在MySQL 8.0.13中已取消支持。
    • ADD DATAFILE在主服务器和从服务器位于同一主机上的复制环境中,不支持该子句。表空间创建不能复制到同一主机上的同一目录。