目录
系统表空间
系统表空间是InnoDB数据字典、doublewrite缓冲区、change缓冲区和undo日志的存储区域。如果表是在系统表空间中创建的,而不是在每个表或常规表空间中创建文件,则它还可能包含表和索引数据。
系统表空间可以有一个或多个数据文件。默认情况下,在数据目录中创建一个名为ibdata1的系统表空间数据文件。系统表空间数据文件的大小和数量由innodb_data_file_path startup选项定义。有关配置信息,see System Tablespace Data File Configuration.
有关系统表空间的其他信息在本节的以下主题下提供:
调整系统表空间的大小
本节介绍如何增加或减少系统表空间的大小。
增加系统表空间的大小
增加系统表空间大小的最简单方法是将其配置为自动扩展。为此,在innodb_data_file_path设置中为最后一个数据文件指定autoextend属性,然后重新启动服务器。例如:
innodb_data_file_path=ibdata1:10MB:autoextend
当指定了autoextend属性时,数据文件的大小会随着空间的需要而自动增加8MB。innodb_autoextend_increment变量控制增量大小。
还可以通过添加另一个数据文件来增加系统表空间大小。为此:
- 停止MySQL服务器。
- 如果innodb_data_file_path设置中的最后一个数据文件是用autoextend属性定义的,那么删除它,并修改size属性以反映当前数据文件的大小。要确定要指定的适当数据文件大小,请检查文件系统中的文件大小,并将该值舍入到最接近的MB值,其中MB等于1024 x 1024。
- 将新的数据文件附加到innodb_data_file_path设置中,可以选择指定autoextend属性。只能为innodb_data_file_path设置中的最后一个数据文件指定autoextend属性。
- 启动MySQL服务器。
例如,此表空间有一个自动扩展的数据文件:
innodb_data_home_dir =
innodb_data_file_path = /ibdata/ibdata1:10M:autoextend
假设数据文件随时间增长到988MB。这是修改size属性以反映当前数据文件大小并指定新的50MB自动扩展数据文件后的innodb_data_file_path设置:
innodb_data_home_dir =
innodb_data_file_path = /ibdata/ibdata1:988M;/disk2/ibdata2:50M:autoextend
添加新的数据文件时,不要指定现有文件名。当您启动服务器时,InnoDB会创建并初始化新的数据文件。
Note
不能通过改变其大小属性来增加现有系统表空间数据文件的大小。例如,将innodb_data_file_path设置从ibdata1:10M:autoextend更改为ibdata1:12M:autoextend会在启动服务器时产生以下错误:
[ERROR] [MY-012263] [InnoDB] The Auto-extending innodb_system data file './ibdata1' is of a different size 640 pages (rounded down to MB) than specified in the .cnf file: initial 768 pages, max 0 (relevant if non-zero) pages!
该错误指示现有的数据文件大小(在YNODB页中表示)与配置文件中指定的大小不同。如果遇到此错误,请恢复先前的
innodb_data_file_path
设置,并参考系统表空间调整说明。InnoDB page size由
innodb_page_size
变量定义。默认值为16384字节。
减少InnoDB系统表空间的大小
您不能从系统表空间中删除数据文件。要减小系统表空间大小,请使用以下过程:
- 使用mysql dump转储所有InnoDB表,包括mysql模式中的InnoDB表。使用以下查询标识mysql模式中的InnoDB表:
mysql> SELECT TABLE_NAME from INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA='mysql' and ENGINE='InnoDB';
+---------------------------+
| TABLE_NAME |
+---------------------------+
| engine_cost |
| gtid_executed |
| help_category |
| help_keyword |
| help_relation |
| help_topic |
| innodb_index_stats |
| innodb_table_stats |
| plugin |
| server_cost |
| servers |
| slave_master_info |
| slave_relay_log_info |
| slave_worker_info |
| time_zone |
| time_zone_leap_second |
| time_zone_name |
| time_zone_transition |
| time_zone_transition_type |
+---------------------------+
- 停止服务器。
- 删除所有现有的表空间文件(*.IBD),包括IBDATA和IBSLO文件。不要忘记删除mysql数据库中表的*.ibd文件。
- 删除InnoDB表的任何.frm文件。
- 为新的系统表空间配置数据文件。请参阅 See System Tablespace Data File Configuration.。
- 重新启动服务器。
- 导入转储文件。
Note
如果数据库只使用InnoDB引擎,那么转储所有数据库、停止服务器、删除所有数据库和InnoDB日志文件、重新启动服务器和导入转储文件可能会更简单。
为了避免系统表空间过大,请考虑对数据使用逐表文件表空间。每个表的文件表空间是默认的表空间类型,并且在创建InnoDB表时被隐式使用。与系统表空间不同,磁盘空间是在截断或删除在每个表空间的文件中创建的表之后返回给操作系统的。有关详细信息,请参阅第14.6.3.2节“每个表空间的文件” Section 14.6.3.2, “File-Per-Table Tablespaces”。
对系统表空间使用原始磁盘分区
可以将原始磁盘分区用作InnoDB系统表空间中的数据文件。这种技术可以在Windows和一些Linux和Unix系统上实现非缓冲I/O,而无需文件系统开销。在有或没有原始分区的情况下执行测试,以验证此更改是否实际提高了系统的性能。
使用原始磁盘分区时,请确保运行MySQL服务器的用户ID具有该分区的读写权限。例如,如果以mysql用户的身份运行服务器,那么mysql必须可读写分区。如果使用 --memlock
选项运行服务器,则服务器必须以root用户身份运行,因此分区必须由root用户可读写。
下面描述的过程涉及选项文件修改。有关更多信息,请参阅第4.2.2.2节“使用选项文件” Section 4.2.2.2, “Using Option Files”.。
在Linux和Unix系统上分配原始磁盘分区
- 创建新数据文件时,请在innodb_data_file_path选项的数据文件大小之后立即指定关键字newraw。分区必须至少与指定的大小相同。注意,InnoDB中的1MB是1024×1024字节,而磁盘规范中的1MB通常意味着1000000字节。
[mysqld]
innodb_data_home_dir=
innodb_data_file_path=/dev/hdd1:3Gnewraw;/dev/hdd2:2Gnewraw
- 重新启动服务器。InnoDB注意到newraw关键字并初始化新分区。但是,不要创建或更改任何InnoDB表。否则,当您下次重新启动服务器时,InnoDB将重新初始化分区,您的更改将丢失。(作为一项安全措施,当指定了任何带有newraw的分区时,InnoDB会阻止用户修改数据。)
- InnoDB初始化新分区后,停止服务器,将数据文件规范中的new raw更改为raw:
[mysqld]
innodb_data_home_dir=
innodb_data_file_path=/dev/hdd1:3Graw;/dev/hdd2:2Graw
- 重新启动服务器。InnoDB现在允许进行更改。
File-Per-Table Tablespaces
一个 file-per-table tablespace包含单个InnoDB表的数据和索引,并存储在文件系统中自己的数据文件中。
本节中的以下主题介绍了 file-per-table tablespace特性:
File-Per-Table Tablespace Configuration
默认情况下,InnoDB在 file-per-table tablespaces中创建表。此行为由 innodb_file_per_table
变量控制。禁用 innodb_file_per_table
会导致innodb在系统表空间中创建表。
innodb_file_per_table
设置可以在选项文件中指定,也可以在运行时使用 SET GLOBAL
语句配置。在运行时更改设置需要足够的权限来设置全局系统变量。. See Section 5.1.8.1, “System Variable Privileges”.
选项文件:
[mysqld]
innodb_file_per_table=ON
SET GLOBAL
在运行时使用:
mysql> SET GLOBAL innodb_file_per_table=ON;
innodb_file_per_table
在MySQL 5.6及更高版本中默认启用。如果担心与早期版本的MySQL向后兼容,可以考虑禁用它。
Warning
禁用innodb_file_per_table可以防止表复制
ALTER TABLE
操作隐式地将系统表空间中的表移动到 file-per-table tablespace.。表复制ALTER TABLE
操作使用当前的innodb_file_per_table
设置重新创建表。此行为不适用于添加或删除辅助索引,也不适用于使用INPLACE算法的ALTER TABLE操作,或不适用于使用CREATE TABLE ... TABLESPACE
或ALTER TABLE ... TABLESPACE
语法添加到系统表空间。
File-Per-Table Tablespace数据文件
在MySQL数据目录下的schema目录中的.idb数据文件中创建 file-per-table tablespace。.ibd文件是为表命名的(table_name.ibd)。例如,表test.t1的数据文件是在MySQL数据目录下的test目录中创建的:
mysql> USE test;
mysql> CREATE TABLE t1 (
id INT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(100)
) ENGINE = InnoDB;
shell> cd /path/to/mysql/data/test
shell> ls
t1.ibd
可以使用CREATE TABLE语句的DATA DIRECTORY子句隐式地为数据目录之外的file-per-table tablespace创建一个文件。更多信息,see Section 14.6.1.2, “Creating Tables Externally”.
File-Per-Table Tablespace的优势
与共享表空间(如系统表空间或通用表空间)相比,File-per-table tablespaces具有以下优势。
- 在截断或删除在 a file-per-table tablespace中创建的表之后,磁盘空间返回到操作系统。运行或删除存储在共享表空间中的表会在共享表空间数据文件中创建可用空间,该文件只能用于InnoDB数据。换句话说,在表被截断或删除后,共享表空间数据文件的大小不会缩小。
- 在共享表空间中的表上执行表复制ALTER table操作可以增加表空间占用的磁盘空间量。这样的操作可能需要与表中的数据加上索引一样多的额外空间。此空间不会释放回操作系统,因为它是针对file-per-table tablespaces的。
- 当对驻留在 file-per-table tablespaces中的表执行
TRUNCATE TABLE
时,性能更好。 - File-per-table tablespace数据文件可以在不同的存储设备上创建,用于I/O优化、空间管理或备份目的。见第14.6.1.2节“外部创建表格”。
- 您可以从另一个MySQL实例导入驻留在file-per-table tablespace 中的表。
- file-per-table tablespaces 中创建的表使用Barracuda文件格式。见14.10节“InnoDB文件格式管理”。Barracuda file格式支持与动态和压缩行格式相关联的功能。见第14.11节,“InnoDB行格式”。
- 存储在单个表空间数据文件中的表可以在发生数据损坏、备份或二进制日志不可用或MySQL服务器实例无法重新启动时节省时间并提高成功恢复的机会。
- 您可以使用MySQL Enterprise backup快速备份或恢复在file-per-table tablespaces中创建的表,而不会中断其他InnoDB表的使用。这对于不同备份计划的表或需要较少备份的表是有益的。有关详细信息,请参见进行部分备份。
- File-per-table tablespaces允许通过监视表空间数据文件的大小来监视文件系统上的表大小。
- 当
innodb_flush_method
设置为O_DIRECT时,常见的Linux文件系统不允许对单个文件(如共享表空间数据文件)进行并发写入。因此,当结合使用 file-per-table tablespaces和此设置时,可能会有性能改进。 - 共享表空间中的表在大小上受64TB表空间大小限制。相比之下,每个表空间的文件都有64TB的大小限制,这为单个表的大小提供了足够的空间。
File-Per-Table Tablespace的缺点
File-per-table tablespaces 与共享表空间(如系统表空间或通用表空间)相比,有以下缺点。
- 对于file-per-table tablespaces,每个表可能都有未使用的空间,这些空间只能由同一表的行使用,如果管理不当,可能会导致浪费空间。
- fsync操作是对每个表数据文件的多个文件而不是单个共享表空间数据文件执行的。由于fsync操作是针对每个文件的,因此不能组合多个表的写操作,这可能导致fsync操作的总数增加。
- mysqld必须为每个file-per-table tablespace保留一个打开的文件句柄,如果file-per-table tablespaces中有许多表,这可能会影响性能。
- 当每个表都有自己的数据文件时,需要更多的文件描述符。
- 可能会出现更多的碎片,这会妨碍
DROP TABLE
和表扫描性能。但是,如果对碎片进行管理,则 file-per-table tablespaces 可以提高这些操作的性能。 - 当删除位于每个表空间的文件中的表时,将扫描缓冲池,对于大型缓冲池,这可能需要几秒钟的时间。扫描是用广泛的内部锁执行的,这可能会延迟其他操作。
- innodb_autoextend_increment变量定义了当共享表空间文件变满时自动扩展共享表空间文件大小的增量大小,但它不适用于 file-per-table tablespace ,无论innodb_autoextend_increment设置如何,这些文件都是自动扩展的。每个表的初始文件表空间扩展名是少量的,之后扩展名以4MB的增量出现。
通用(General)表空间
通用表空间是使用 CREATE TABLESPACE
语法创建的一个共享InnoDB表空间。本节中的以下主题介绍了一般(General)表空间功能和特性:
常规表空间功能
常规表空间功能提供以下功能:
- 类似于系统表空间,常规表空间是共享表空间,可以存储多个表的数据。
- 常规表空间比 file-per-table tablespaces.表空间具有潜在的内存优势 。服务器在表空间的生存期内将表空间元数据保留在内存中。较少的常规表空间中的多个表与单独的每表文件表空间中相同数量的表相比,为表空间元数据消耗的内存更少。
- 一般表空间数据文件可以放在相对于或独立于MySQL数据目录的目录中,该目录为您提供了 file-per-table tablespaces的许多数据文件和存储管理功能。与 file-per-table tablespaces一样,将数据文件放在MySQL数据目录之外的功能允许您分别管理关键表的性能,为特定表设置RAID或DRBD,或者将表绑定到特定磁盘。
- 常规表空间支持Antelope和Barracuda文件格式,因此支持所有表行格式和相关功能。支持两种文件格式,通用表空间不依赖
innodb_file_format
或innodb_file_per_table
设置,这些变量也不影响通用表空间。 TABLESPACE
选项可用于CREATE TABLE
在常规表空间,file-per-table tablespace或系统表空间中创建表。- 该
TABLESPACE
选项可与ALTER TABLE一起用于在常规表空间,file-per-table tablespaces和系统表空间之间移动表。以前,不可能将表从file-per-table tablespaces移动到系统表空间。使用常规表空间功能,您现在可以这样做。
创建通用表空间
常规表空间是使用CREATE TABLESPACE
语法创建的 。
CREATE TABLESPACE tablespace_name
ADD DATAFILE 'file_name'
[FILE_BLOCK_SIZE = value]
[ENGINE [=] engine_name]
通用表空间可以在数据目录中或在其外部创建。为避免与隐式创建的file-per-table tablespaces冲突,不支持在数据目录下的子目录中创建常规表空间。在数据目录之外创建常规表空间时,该目录必须在创建表空间之前存在。
当在MySQL数据目录之外创建常规表空间时,将在MySQL数据目录中创建一个.isl文件。
Examples:
在数据目录中创建常规表空间:
mysql> CREATE TABLESPACE `ts1` ADD DATAFILE 'ts1.ibd' Engine=InnoDB;
在数据目录之外的目录中创建常规表空间:
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
or 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版本中将不再支持该功能。共享表空间包括
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
值也可以指定为字节。要确定给定 FILE_BLOCK_SIZE
的有效键块大小值,请将文件块大小值除以1024。32K和64K InnoDB页面大小不支持表压缩。有关键块大小的详细信息,请参见创建表,and Section 14.9.1.2, “Creating Compressed Tables”.
Permitted Page Size, FILE_BLOCK_SIZE, and KEY_BLOCK_SIZE Combinations for Compressed Tables
InnoDB Page Size (innodb_page_size) | Permitted FILE_BLOCK_SIZE Value | Permitted KEY_BLOCK_SIZE Value |
---|---|---|
64KB | 64K (65536) | Compression is not supported |
32KB | 32K (32768) | Compression is not supported |
16KB | 16K (16384) | N/A: If innodb_page_size is equal to FILE_BLOCK_SIZE , the tablespace cannot contain a compressed table. |
16KB | 8K (8192) | 8 |
16KB | 4K (4096) | 4 |
16KB | 2K (2048) | 2 |
16KB | 1K (1024) | 1 |
8KB | 8K (8192) | N/A: If innodb_page_size is equal to FILE_BLOCK_SIZE , the tablespace cannot contain a compressed table. |
8KB | 4K (4096) | 4 |
8KB | 2K (2048) | 2 |
8KB | 1K (1024) | 1 |
4KB | 4K (4096) | N/A: If innodb_page_size is equal to FILE_BLOCK_SIZE , the tablespace cannot contain a compressed table. |
4K | 2K (2048) | 2 |
4KB | 1K (1024) | 1 |
此示例演示如何创建常规表空间和添加压缩表。该示例假设innodb_page_的默认大小为16KB。文件块大小8192要求压缩表的键块大小为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
, and DYNAMIC
row formats)的表。
使用ALTER TABLE在表空间之间移动表
您可以使用ALTER TABLE
该 TABLESPACE
选项将表移动到现有的常规表空间,新的 file-per-table tablespace,或系统表空间。
注意MySQL 5.7.24中弃用了将表分区放置在共享表空间中的支持,并且在将来的MySQL版本中将不再支持。共享表空间包括
InnoDB
系统表空间和常规表空间。
要将表从 file-per-table tablespace或系统表空间移至常规表空间,请指定常规表空间的名称。常规表空间必须存在。请参阅 CREATE TABLESPACE
以获取更多信息。
ALTER TABLE tbl_name TABLESPACE [=] tablespace_name;
要将表从一般表空间或rfile-per-table tablespace移到系统表空间,请指定innodb_system作为表空间名称。
ALTER TABLE tbl_name TABLESPACE [=] innodb_system;
要将表从系统表空间或常规表空间移动到 file-per-table tablespace,请指定innodb_file_per_table作为表空间名称。
ALTER TABLE tbl_name TABLESPACE [=] innodb_file_per_table;
ALTER TABLE ... TABLESPACE
操作总是会导致完整的表重建,即使表空间属性与其前一个值没有更改。
ALTER TABLE ... TABLESPACE
语法不支持将表从临时表空间移动到持久表空间。
CREATE TABLE ... TABLESPACE=innodb_file_per_table
允许使用DATA DIRECTORY
子句,但不支持与TABLESPACE选项结合使用。
从加密表空间中移动表时应用限制。请参见加密限制。 See Encryption Limitations.
Dropping a General Tablespace
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 |
+------------+------------+
如果空的通用表空间上的删除表空间操作返回错误,则表空间可以包含由服务器退出中断的 ALTER TABLE
操作所遗留的孤儿临时表或中间表。 see Section 14.22.3, “Troubleshooting InnoDB Data Dictionary Operations”.
当删除表空间中的最后一个表时,一般的InnoDB表空间不会自动删除。必须使用 DROP TABLESPACE
.显式删除表空间。tablespace_name
一般表空间不属于任何特定的数据库。DROP DATABASE操作可以删除属于常规表空间的表,但不能删除表空间,即使DROP DATABASE操作删除了属于该表空间的所有表。必须使用 DROP TABLESPACE
.显式删除常规表空间。tablespace_name
与系统表空间类似,截断或删除存储在通用表空间中的表会在通用表空间.ibd数据文件内部创建可用空间,该文件只能用于新的InnoDB数据。空间不会释放回操作系统,因为在 DROP TABLE
操作过程中删除了file-per-table tablespace。
这个例子演示了如何删除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
常规表空间限制
-
生成的或现有的表空间无法更改为常规表空间。
-
不支持创建临时通用表空间。
-
常规表空间不支持临时表。
-
通用表空间中存储的表只能在支持通用表空间的MySQL版本中打开。
-
与系统表空间类似,截断或删除存储在通用表空间中的表会在通用表空间.ibd数据文件内部创建可用空间,该文件只能用于新的InnoDB数据。空间不会释放回操作系统,因为它是针对 file-per-table tablespaces。
此外,对驻留在共享表空间(一般表空间或系统表空间)中的表执行表复制 ALTER TABLE
操作可以增加表空间使用的空间量。这样的操作需要的额外空间与表中的数据加上索引一样多。table-copying ALTER TABLE
操作所需的额外空间不会释放回操作系统,因为它是针对 file-per-table tablespaces的。
-
ALTER TABLE ... DISCARD TABLESPACE
andALTER TABLE ...IMPORT TABLESPACE
不支持属于常规表空间的表。 -
在MySQL 5.7.24中,不支持将表分区放在常规表空间中,并将在以后的MySQL版本中删除。
Undo Tablespaces
撤消表空间包含撤消日志,撤消日志是撤消日志记录的集合,其中包含有关如何撤消事务对聚集索引记录的最新更改的信息。撤消日志存在于撤消日志段中,这些日志段包含在回滚段中。innodb_rollback_segments变量定义分配给每个撤消表空间的回滚段数。
撤消日志可以存储在一个或多个撤消表空间中,而不是存储在系统表空间中。此布局与系统表空间中存在撤消日志的默认配置不同。undo日志的I/O模式使undo表空间很适合SSD存储,同时将系统表空间保留在硬盘存储上。
InnoDB使用的undo表空间的数量由InnoDB_undo_tablespaces配置选项控制。此选项只能在初始化MySQL实例时配置。以后不能更改。
注意该
innodb_undo_tablespaces
配置选项已弃用,在以后的版本中将被删除。
撤消表空间和这些表空间中的各个段不能被删除。但是,存储在undo表空间中的undo日志可以被截断。有关详细信息,请参见截断撤消表空间。
Configuring Undo Tablespaces
要为MySQL实例配置撤消表空间,请执行以下步骤。假设在将配置部署到生产系统之前,您正在测试实例上执行该过程。
Important
只有在初始化MySQL实例时才能配置undo表空间的数量,并且在实例的生命周期内是固定的。
- 使用
innodb_undo_directory
配置选项指定撤消表空间的目录位置。如果未指定目录位置,则在数据目录中创建撤消表空间。 - 使用
innodb_rollback_segments
配置选项定义回滚段的数量。从一个相对较低的值开始,并随着时间的推移逐渐增加它,以检查对性能的影响。对于innodb_rollback_segments
的默认设置是128,这也是最大值。 一个回滚段始终分配给系统表空间,32个回滚段保留给临时表空间(ibtmp1)。因此,要分配回滚段来撤消表空间,请将innodb_rollback_segments设置为大于33的值。例如,如果有两个撤销表空间,那么将innodb_rollback_segments设置为35,以便为两个撤销表空间中的每一个分配一个回滚段。回滚段以循环方式分布在撤消表空间中。 配置单独的撤消表空间时,系统表空间中的回滚段将呈现为非活动状态. - 使用innodb_undo_tablespaces选项定义undo表空间的数量。在MySQL实例的生命周期中,指定数量的撤消表空间是固定的,因此如果您不确定最佳值,请从较高的方面进行估计。
- 使用您选择的选项值创建一个新的MySQL测试实例。
- 在测试实例上使用与生产服务器类似的数据量的实际工作负载来测试配置。
- 对I/O密集型工作负载的性能进行基准测试。
- 定期增加
innodb_rollback_segments
的值,并重新运行性能测试,直到I/O性能没有进一步提高为止。
截断撤消表空间Truncating Undo Tablespaces
截断undo表空间要求MySQL实例至少有两个活动的undo表空间,这样可以确保一个undo表空间保持活动状态,而另一个将脱机以截断。undo tablespaces的数量由innodb_undo_tablespaces变量定义。默认值为0。使用此语句检查innodb_undo_表空间的值:
mysql> SELECT @@innodb_undo_tablespaces;
+---------------------------+
| @@innodb_undo_tablespaces |
+---------------------------+
| 2 |
+---------------------------+
要截断undo表空间,请启用innodb_undo_log_truncate变量。例如:
mysql> SET GLOBAL innodb_undo_log_truncate=ON;
启用innodb_undo_log_truncate变量时,超过innodb_max_undo_log_size变量定义的大小限制的undo表空间将被截断。innodb_max_undo_log_size变量是动态的,默认值为1073741824字节(1024 MiB)。
mysql> SELECT @@innodb_max_undo_log_size;
+----------------------------+
| @@innodb_max_undo_log_size |
+----------------------------+
| 1073741824 |
+----------------------------+
启用innodb_undo_log_truncate变量时:
- 超过innodb_max_Undo_log_size设置的Undo表空间被标记为截断。选择要截断的撤消表空间是以循环方式执行的,以避免每次截断相同的撤消表空间。
- 驻留在所选撤消表空间中的回滚段处于非活动状态,因此不会将它们分配给新事务。当前使用回滚段的现有事务被允许完成。
- 清除系统释放不再使用的回滚段。
- 在撤消表空间中的所有回滚段被释放后,truncate操作将运行并将撤消表空间截断为其初始大小。撤消表空间的初始大小取决于innodb_page_size值。对于默认的16KB页面大小,初始的撤消表空间文件大小为10MiB。对于4KB、8KB、32KB和64KB的页面大小,初始的撤消表空间文件大小分别为7MiB、8MiB、20MiB和40MiB。
- 由于在操作完成后立即使用,truncate操作后撤消表空间的大小可能大于初始大小。
-
innodb_undo_directory
变量定义undo表空间文件的位置。如果innodb_undo_directory
变量未定义,则undo表空间位于data目录中。 - 回滚段将重新激活,以便可以将它们分配给新事务。
加快撤消表空间的截断
清除线程负责清空和截断撤消表空间。默认情况下,清除线程会查找撤消表空间,以便在调用清除时每128次截断一次。清除线程查找要截断的撤消表空间的频率由 innodb_purge_rseg_truncate_frequency
变量控制,该变量的默认设置为128。
mysql> SELECT @@innodb_purge_rseg_truncate_frequency;
+----------------------------------------+
| @@innodb_purge_rseg_truncate_frequency |
+----------------------------------------+
| 128 |
+----------------------------------------+
要增加该频率,请减小innodb_purge_rseg_truncate_frequency设置。例如,要让purge线程每调用一次purge就查找一次undo tabespace,请将innodb_purge_rseg_truncate_frequency设置为32。
mysql> SET GLOBAL innodb_purge_rseg_truncate_frequency=32;
当清除线程发现需要截断的撤消表空间时,清除线程以更高的频率返回,以快速清空并截断撤消表空间。
截断撤消表空间文件的性能影响
撤消表空间被截断时,撤消表空间中的回滚段将被停用。其他撤消表空间中的活动回滚段负责整个系统负载,这可能会导致性能轻微下降。性能下降的程度取决于许多因素:
-
撤消表空间的数量
-
撤消日志数
-
撤消表空间大小
-
I / O承载系统的速度
-
现有的长期交易
-
系统负荷
截断撤消表空间时避免影响性能的最简单方法是增加撤消表空间的数量。
临时表空间
由用户创建的非压缩临时表和磁盘内部临时表是在共享临时表空间中创建的 innodb_temp_data_file_path
配置选项定义临时表空间数据文件的相对路径、名称、大小和属性。如果没有为innodb_temp_data_file_path指定值,默认行为是在innodb_data_home_dir目录中创建一个名为ibtmp1的自动扩展数据文件,该文件略大于12MB。
Note
在MySQL 5.6中,非压缩的临时表是在临时文件目录中的每个表空间中创建的,如果禁用了
innodb_file_per_table
,则在数据目录中的InnoDB system表空间中创建。在MySQL 5.7中引入共享临时表空间,可以降低为每个临时表创建和删除file-per-table tablespace 所带来的性能成本。专用的临时表空间还意味着不再需要将临时表元数据保存到InnoDB系统表中。
压缩临时表是使用ROW_FORMAT=Compressed属性创建的临时表,在临时文件目录中的每个表空间的文件中创建。
临时表空间在正常关机或中止初始化时被删除,并在每次启动服务器时重新创建。临时表空间在创建时接收动态生成的空间ID。如果无法创建临时表空间,则拒绝启动。如果服务器意外停止,则不会删除临时表空间。在这种情况下,数据库管理员可以手动删除临时表空间或重新启动服务器,服务器将自动删除并重新创建临时表空间。
临时表空间不能位于原始设备上。
INFORMATION_SCHEMA.FILES
提供关于InnoDB临时表空间的元数据。发出与此类似的查询以查看临时表空间元数据:
mysql> SELECT * FROM INFORMATION_SCHEMA.FILES WHERE TABLESPACE_NAME='innodb_temporary'\G
INFORMATION_SCHEMA.INNODB_TEMP_TABLE_INFO
提供有关用户创建的临时表的元数据,这些临时表当前在INNODB实例中处于活动状态。有关更多信息, see Section 14.16.7, “InnoDB INFORMATION_SCHEMA Temporary Table Info Table”.
管理临时表空间数据文件大小
默认情况下,临时表空间数据文件是自动扩展的,并且会根据需要增加其大小以容纳磁盘上的临时表。例如,如果某个操作创建的临时表大小为20MB,则临时表空间数据文件(在创建时默认为12MB)将扩展大小以容纳该表。删除临时表后,释放的空间可用于新的临时表,但数据文件将保持扩展大小。
在使用大型临时表或广泛使用临时表的环境中,自动扩展临时表空间数据文件可能会变得很大。使用临时表的长时间运行的查询也可能导致数据文件很大。
要确定临时表空间数据文件是否正在自动扩展,请检查以下 innodb_temp_data_file_path
设置:
mysql> SELECT @@innodb_temp_data_file_path;
+------------------------------+
| @@innodb_temp_data_file_path |
+------------------------------+
| ibtmp1:12M:autoextend |
+------------------------------+
要检查临时表空间数据文件的大小,请使用类似以下的查询查询INFORMATION_SCHEMA.files表:
mysql> SELECT FILE_NAME, TABLESPACE_NAME, ENGINE, INITIAL_SIZE, TOTAL_EXTENTS*EXTENT_SIZE
AS TotalSizeBytes, DATA_FREE, MAXIMUM_SIZE FROM INFORMATION_SCHEMA.FILES
WHERE TABLESPACE_NAME = 'innodb_temporary'\G
*************************** 1. row ***************************
FILE_NAME: ./ibtmp1
TABLESPACE_NAME: innodb_temporary
ENGINE: InnoDB
INITIAL_SIZE: 12582912
TotalSizeBytes: 12582912
DATA_FREE: 6291456
MAXIMUM_SIZE: NULL
TotalSizeBytes值报告临时表空间数据文件的当前大小。有关其他字段值的信息,请参阅第24.9节“信息架构文件表”。
或者,检查操作系统上的临时表空间数据文件大小。默认情况下,临时表空间数据文件位于 innodb_temp_data_file_path
配置选项定义的目录中。如果未显式为此选项指定值,则在innodb_data_home_dir
中创建名为ibtmp1的临时表空间数据文件,如果未指定,则默认为MySQL数据目录。
要回收临时表空间数据文件占用的磁盘空间,请重新启动MySQL服务器。重新启动服务器会根据 innodb_temp_data_file_path
定义的属性删除并重新创建临时表空间数据文件。
为了防止临时数据文件变得太大,可以配置 innodb_temp_data_file_path
选项来指定最大文件大小。例如:
[mysqld]
innodb_temp_data_file_path=ibtmp1:12M:autoextend:max:500M
当数据文件达到最大大小时,查询失败,指示表已满的错误。配置innodb_temp_data_file_path需要重新启动服务器。
或者,配置 default_tmp_storage_engine
和 internal_tmp_disk_storage_engine
选项,这些选项分别定义要用于用户创建的和磁盘上的内部临时表的存储引擎。默认情况下,这两个选项都设置为InnoDB。MyISAM存储引擎为每个临时表使用一个单独的文件,该文件在删除临时表时被删除。