ITPub博客

首页 > 数据库 > > 14.7 InnoDB 表空间

14.7 InnoDB 表空间

作者:飘絮絮絮丶 时间:2020-05-12 09:59:29 0 删除 编辑

参考官方文档:
dev.mysql.com/doc/refma



14.7.1 调整InnoDB系统表空间的大小


本节介绍如何增加或减少InnoDB系统表空间的大小。


增加 InnoDB 系统表空间的大小


增加InnoDB系统表空间大小的最简单方法是使用自动扩展。 为表空间定义中的最后一个数据文件指定autoextend属性。 然后InnoDB在空间不足时以64MB为增量自动增加该文件的大小。 增量大小可以通过设置innodb_autoextend_increment系统变量的值来改变,该变量以兆字节为单位。


您可以通过添加另一个数据文件将系统表空间扩展一个指定的数量:


1.停止mysql 服务
2.如果前一个数据文件是使用关键字autoextend定义的,则根据其实际增长的大小将其定义更改为使用固定大小。 检查数据文件的大小,将其舍入到1024×1024字节(= 1MB)的最接近倍数,并在innodb_data_file_path中明确指定该舍入大小。
3.将一个新的数据文件添加到innodb_data_file_path的末尾,可选择使该文件自动扩展。 只有innodb_data_file_path中的最后一个数据文件可以指定为自动扩展。
4.重启启动 MYSQL 服务


例如,这个表空间只有一个自动扩展的数据文件ibdata1:


innodb_data_home_dir = innodb_data_file_path = /ibdata/ibdata1:10M:autoextend


假设这个数据文件随着时间的推移已经增长到了988MB。 修改原始数据文件以使用固定大小并添加新的自动扩展数据文件后,以下是配置行:


innodb_data_home_dir = innodb_data_file_path = /ibdata/ibdata1:988M;/disk2/ibdata2:50M:autoextend


将新数据文件添加到系统表空间配置时,请确保文件名不引用现有文件。 InnoDB在重新启动服务器时创建并初始化文件。




减少 InnoDB系统表空间的大小


您不能从系统表空间中删除数据文件。 要减小系统表空间大小,请使用以下过程:


1.使用mysqldump转储所有InnoDB表,包括位于MySQL数据库中的InnoDB表。 从5.6开始,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 |
+---------------------------+

  1. 关闭服务器
  2. 删除所有现有的表空间文件(* .ibd),包括ibdata和ib_log文件。 不要忘记删除位于MySQL数据库中的表的* .ibd文件。
  3. 为 InnoDB表移除任何.frm文件
  4. 配置新表空间
  5. 重启服务
  6. 导入dump文件



注意:
如果您的数据库仅使用InnoDB引擎,则转储所有数据库,停止服务器,删除所有数据库和InnoDB日志文件,重新启动服务器以及导入转储文件可能会更简单。


14.7.2 更改InnoDB重做日志文件的数量或大小


1.停止MySQL服务器并确保它关闭而没有错误。


2.编辑my.cnf以更改日志文件配置。 要更改日志文件大小,请配置innodb_log_file_size。 要增加日志文件的数量,请配置innodb_log_files_in_group。


3.启动MYSQL 服务器


如果InnoDB检测到innodb_log_file_size与重做日志文件大小不同,它会写入日志检查点,关闭并删除旧的日志文件,以请求的大小创建新的日志文件并打开新的日志文件



14.7.4 InnoDB File-Per-Table 表空间




从历史上看,所有InnoDB表和索引都存储在系统表空间中。 这种单一的方法针对的是专门用于数据库处理的机器,精心策划数据增长,其中任何分配给MySQL的磁盘存储都不会用于其他目的。 InnoDB的每表文件表空间功能提供了更灵活的选择,每个InnoDB表及其索引都存储在单独的.ibd数据文件中。 每个这样的.ibd数据文件代表一个单独的表空间。 该功能由innodb_file_per_table配置选项控制,该选项在MySQL 5.6.6及更高版本中默认启用。


每个表文件 表空间的优势

  • 在截断或删除存储在每个文件表的表空间中的表时,可以回收磁盘空间。 截断或删除存储在共享系统表空间中的表将在系统表空间数据文件(ibdata文件)的内部创建空闲空间,这些文件只能用于新的InnoDB数据。



同样,在表上复制ALTER TABLE操作(驻留在共享表空间中)可以增加表空间使用的空间量。 这些操作可能需要与表中的数据和索引一样多的额外空间。 表复制ALTER TABLE操作所需的额外空间不会释放回操作系统,因为它是针对每个表文件的表空间。

  • 在存储在每个表文件的表空间中存储的表上运行时,TRUNCATE TABLE操作速度更快。
  • 您可以将特定表存储在单独的存储设备上,用于I / O优化,空间管理或备份目的。 在以前的版本中,您必须将整个数据库目录移动到其他驱动器,并在MySQL数据目录中创建符号链接,如第8.12.3节“使用符号链接”中所述。 在MySQL 5.6.6及更高版本中,可以使用语法CREATE TABLE ... DATA DIRECTORY = absolute_path_to_directory指定每个表的位置,如第14.7.5节“在数据目录之外创建每个文件表空间”。


  • 您可以运行OPTIMIZE TABLE来压缩或重新创建每个文件表的表空间。 当您运行OPTIMIZE TABLE时,InnoDB将使用临时名称创建一个新的.ibd文件,仅使用存储实际数据所需的空间。 优化完成后,InnoDB将删除旧的.ibd文件并将其替换为新的.ibd文件。 如果以前的.ibd文件显着增长,但实际数据仅占其大小的一部分,则运行OPTIMIZE TABLE可以回收未使用的空间。
  • 您可以移动各个InnoDB表而不是整个数据库。
  • 您可以将单个InnoDB表从一个MySQL实例复制到另一个(称为可移动表空间功能)。
  • 以每个文件表格空间创建的表格使用 Barracuda文件格式。 Barracuda文件格式支持压缩和动态行格式等功能。
  • 你可以为BLOB活TEXT字段使用动态行格式来启用更高效的存储。
  • 文件每表的表空间可能会提高成功恢复的几率,并在发生损坏时,服务器无法重新启动或备份和二进制日志不可用时节省时间。
  • 在复制或备份表格时,每个表文件表空间便于每个的状态报告。
  • 您可以在文件系统级别监视表大小,而无需访问MySQL。
  • 当innodb_flush_method设置为O_DIRECT时,通用Linux文件系统不允许并发写入单个文件。 因此,在将innodb_flush_method与每个表的文件表空间结合使用时,性能可能得到改进。
  • 系统表空间存储数据字典和undo日志,并且受InnoDB表空间大小限制的限制。 请参见第14.8.1.7节“InnoDB表的限制”。 通过每个表文件的表空间,每个表都有其自己的表空间,这为增长空间提供了空间。



每个文件-表的表空间 潜在缺点

  • 对于每个表文件的表空间,每个表可能有未使用的空间,这些空间只能被同一个表的行使用。 如果管理不当,这可能会导致浪费空间。
  • fsync操作必须在每个打开的表上运行,而不是在单个文件上运行。 由于每个文件都有单独的fsync操作,因此多个表上的写操作不能合并为单个I/O操作。 这可能需要InnoDB执行更多的fsync操作。
  • mysqld必须为每个表保留一个打开的文件句柄,如果在每个表的文件表空间中有大量表,则这可能会影响性能。
  • 使用更多的文件描述符。
  • Innodb_file_per_table默认在MySQL 5.6.6及更高版本中启用。 如果向后兼容MySQL 5.5或5.1,你可以考虑禁用它。 在ALTER TABLE重新创建表(ALGORITHM = COPY)的情况下,禁用innodb_file_per_table会阻止ALTER TABLE将InnoDB表从系统表空间移动到单个.ibd文件。
  • 如果许多表正在增长,则可能会出现更多碎片,从而可能会阻碍DROP TABLE和表扫描性能。 但是,当碎片被整理时,将文件放在其自己的表空间中可以提高性能。
  • 删除每个表文件的表空间时会扫描缓冲池,对于数十GB的缓冲池,这可能需要几秒钟的时间。 扫描采用广泛的内部锁执行,这可能会延迟其他操作。 系统表空间中的表不受影响。
  • innodb_autoextend_increment变量定义了用于在自动扩展共享表空间文件变满时扩展大小的增量大小(以MB为单位),无论innodb_autoextend_increment为多少,该变量不适用于每个文件每表的表空间。 最初的扩展是少量的,之后扩展以4MB为增量进行。



14.7.5 在 数据目录之外创建 每个文件-表的表空间



使用CREATE TABLE语句的DATA DIRECTORY = absolute_path_to_directory子句。


提前计划位置,因为您不能使用DATA DIRECTORY子句和ALTER TABLE语句来稍后更改位置。 您指定的目录可能位于具有特定性能或容量特性的其他存储设备上,如快速SSD或高容量HDD。


在目标目录中,MySQL创建一个与数据库名相对应的子目录,并在其中创建新表的.ibd文件。 在MySQL DATADIR目录下的数据库目录中,MySQL创建一个包含表的路径名的table_name.isl文件。 .isl文件被MySQL视为符号链接。 (使用实际的符号链接从未被InnoDB表支持。)


以下示例演示了在MySQL数据目录之外创建一个每表文件表的表空间。 它显示在指定目录中创建的.ibd文件以及在MySQL数据目录下的数据库目录中创建的.isl文件。


mysql> USE test;
Database changed
mysql> SHOW VARIABLES LIKE 'innodb_file_per_table';

+-----------------------+-------+
| Variable_name | Value |
+-----------------------+-------+

| innodb_file_per_table | ON |

+-----------------------+-------+
mysql>
CREATE TABLE t1 (c1 INT PRIMARY KEY) DATA DIRECTORY = '/alternative/directory';

# MySQL creates a .ibd file for the new table in a subdirectory that corresponding # to the database name db_user@ubuntu:~/alternative/directory/test$ ls t1.ibd # MySQL creates a .isl file containing the path name for the table in a directory # beneath the MySQL data directory db_user@ubuntu:~/mysql/data/test$ ls db.opt t1.frm t1.isl


您还可以将CREATE TABLE ... TABLESPACE与DATA DIRECTORY子句结合使用,在MySQL数据目录之外创建一个每个文件-表的表空间。 为此,您必须指定innodb_file_per_table作为表空间名称。


mysql> CREATE TABLE t2 (c1 INT PRIMARY KEY) TABLESPACE = innodb_file_per_table DATA DIRECTORY = '/alternative/directory';


使用此方法时,您不必启用innodb_file_per_table。


使用注意:

  • MySQL最初将.ibd文件保存为打开状态,从而阻止您卸载该设备,但如果服务器繁忙,最终可能会关闭该表。 小心不要在MySQL运行时意外卸载外部设备,或者在设备断开连接时启动MySQL。 尝试在关联的.ibd文件丢失时访问表会导致需要重新启动服务器的严重错误。


如果.ibd文件仍然不在预期路径中,服务器重新启动可能会失败。 在这种情况下,请手动删除数据库目录中的table_name.isl文件,重新启动后执行DROP TABLE以删除.frm文件并从数据字典中删除有关该表的信息。

  • 在将表放置在安装了NFS的卷上之前,请查看使用NFS与MySQL中概述的潜在问题


  • 如果使用LVM快照,文件副本或其他基于文件的机制来备份.ibd文件,请始终首先使用FLUSH TABLES ... FOR EXPORT语句,以确保在备份发生之前,内存中缓冲的所有更改都被刷新到磁盘。
  • DATA DIRECTORY子句是受支持的使用符号链接的替代方法,不支持单个InnoDB表。


    14.7.6 拷贝 每个文件-表的表空间到其他实例


    本节介绍如何将每个表文件的表空间从一个MySQL实例复制到另一个MySQL实例,也称为可传输表空间功能。


    有很多原因需要将InnoDB文件 - 每表表空间复制到其他实例:

  • 产生报告而不会在生产服务器上增加额外的负载。
  • 在新的从服务器上为表设置相同的数据。
  • 在出现问题或错误后恢复表或分区的备份版本。
  • 作为一种快速移动数据的方式,而不是导入mysqldump命令的结果。 数据立即可用,而不必重新插入并重建索引。
  • 将每个文件表的表空间移动到具有更适合系统要求的存储介质的服务器。 例如,您可能希望在SSD设备上存放繁忙表,或者在高容量HDD设备上存放大型表。



限制和使用说明:

  • 只有当innodb_file_per_table设置为ON(默认设置)时才可以执行表空间复制过程。 驻留在共享系统表空间中的表不能被停顿。
  • 当表被停顿时,受影响的表上只允许只读事务。
  • 导入表空间时,页面大小必须与导入实例的页面大小相匹配。
  • 当foreign_key_checks设置为1时,DISCARD TABLESPACE不支持具有父 - 子(主键 - 外键)关系的表空间。在放弃父 - 子表的表空间之前,请设置foreign_key_checks = 0。 分区的InnoDB表不支持外键。
  • ALTER TABLE ... IMPORT TABLESPACE不强制导入数据的外键约束。 如果表之间存在外键约束,则应该在同一(逻辑)时间点导出所有表。 分区的InnoDB表不支持外键。
  • ALTER TABLE ... IMPORT TABLESPACE和ALTER TABLE ... IMPORT PARTITION ... TABLESPACE不需要.cfg元数据文件来导入表空间。 但是,导入没有.cfg文件时不会执行元数据检查,并会发出类似于以下内容的警告:



Message: InnoDB: IO Read error: (2, No such file or directory) Error opening '.\ test\t.cfg',
will attempt to import without schema verification
1 row in set (0.00 sec)


当没有期望的方案匹配时,没有.cfg文件的情况下导入的能力可能会更方便。 另外,无法从.ibd文件收集元数据的崩溃恢复方案中,不使用.cfg文件进行导入的功能也可能很有用。

  • 由于.cfg元数据文件的限制,当为分区表导入表空间文件时,不会为分区类型或分区定义差异报告模式不匹配。 报告列差异。
  • 当在子分区表上运行ALTER TABLE ... DISCARD PARTITION ... TABLESPACE和ALTER TABLE ... IMPORT PARTITION ... TABLESPACE时,允许分区和子分区表的命名。 当指定分区名称时,该分区的子分区将包含在该操作中。
  • 如果两个实例都具有GA(通用可用性)状态并且它们的版本在同一个系列中,则从另一个MySQL服务器实例导入表空间文件将起作用。 否则,该文件必须已在与其导入的服务器实例相同的服务器实例上创建。
  • 在复制环境中,mastere和slave上的innodb_file_per_table必须设置为ON。
  • 在Windows上,InnoDB以小写内部存储数据库,表空间和表名。 为避免在区分大小写的操作系统(如Linux和UNIX)上导入问题,请使用小写名称创建所有数据库,表空间和表。 完成此操作的一种便捷方法是在创建数据库,表空间或表之前,将以下行添加到my.cnf或my.ini文件的[mysqld]部分中:


[mysqld]
lower_case_table_names=1

  • ALTER TABLE ... DISCARD TABLESPACE和ALTER TABLE ... IMPORT TABLESPACE不支持属于InnoDB常规表空间的表。 有关更多信息,请参阅CREATE TABLESPACE。
  • InnoDB表的默认行格式可以使用innodb_default_row_format配置选项进行配置。 尝试导入未明确定义行格式(ROW_FORMAT)或使用ROW_FORMAT = DEFAULT的表时,如果源实例上的innodb_default_row_format设置与目标实例上的设置不同,则可能导致方案不匹配错误。
  • 当导出使用InnoDB表空间加密功能加密的表空间时,除了.cfg元数据文件外,InnoDB还会生成.cfp文件。 在对目标实例执行ALTER TABLE ... IMPORT TABLESPACE操作之前,必须将.cfp文件与.cfg文件和表空间文件一起复制到目标实例。 .cfp文件包含一个传输密钥和一个加密的表空间密钥。 在导入时,InnoDB使用传输密钥来解密表空间密钥。
  • FLUSH TABLES ... FOR EXPORT在具有FULLTEXT索引的表上不受支持。 全文搜索辅助表不会被刷新。 在导入带有FULLTEXT索引的表后,运行OPTIMIZE TABLE以重建FULLTEXT索引。 或者,在导出操作之前删除FULLTEXT索引,并在目标实例上导入表后重新创建索引。


14.7.6.1 表空间传输例子

例子1:拷贝InnoDB 表到另一个实例


此过程演示如何将正在运行的MySQL服务器实例的InnoDB表复制到另一个正在运行的实例。 通过较小的调整,可以使用相同的过程在同一个实例上执行全表恢复。


1.在源实例上,如果不存在,则创建的表:


mysql> USE test;
mysql> CREATE TABLE t(c1 INT) ENGINE=InnoDB;


2.在目标实例上,如果不存在,则创建的表:


mysql> USE test;
mysql> CREATE TABLE t(c1 INT) ENGINE=InnoDB;


3.在目标实例上,放弃现有的表空间。 (在导入表空间之前,InnoDB必须丢弃要附加的接收表的表空间。)


mysql> ALTER TABLE t DISCARD TABLESPACE;


4.在源实例上,运行FLUSH TABLES ... FOR EXPORT以停顿表并创建.cfg元数据文件:


mysql> USE test;
mysql> FLUSH TABLES t FOR EXPORT;


元数据(.cfg)在InnoDB数据目录中被创建。


注意:
FLUSH TABLES ... FOR EXPORT语句确保对指定表的更改已刷新到磁盘,以便在实例运行时可以创建二进制表副本。 当FLUSH TABLES ... FOR EXPORT运行时,InnoDB在与表相同的数据库目录中生成一个.cfg文件。 .cfg文件包含导入表空间文件时用于方案验证的元数据。


5.将.ibd文件和.cfg元数据文件从源实例复制到目标实例。 例如:


shell> scp /path/to/datadir/test/t.{ibd,cfg} destination-server:/path/to/datadir/test


注意:
如下一步所述,必须在释放共享锁之前复制.ibd文件和.cfg文件。


6.在源实例上,使用UNLOCK TABLES释放由 FLUSH TABLES ... FOR EXPORT 获取的锁:
mysql> USE test;
mysql> UNLOCK TABLES;


7.在目标实例,导入表空间:


mysql> USE test;
mysql> ALTER TABLE t IMPORT TABLESPACE;


注意:


ALTER TABLE ... IMPORT TABLESPACE功能不强制导入数据的外键约束。 如果表之间存在外键约束,则应该在相同(逻辑)时间点导出所有表。 在这种情况下,您将停止更新表,提交所有事务,获取表上的共享锁,然后执行导出操作。


例子2:将InnoDB分区表复制到另一个实例


此过程演示如何将分区的InnoDB表从正在运行的MySQL服务器实例复制到另一个正在运行的实例。 经过较小调整的相同过程可用于在同一实例上执行InnoDB分区表的完整恢复。


1.在源实例上,创建一个分区表(如果不存在)。 在以下示例中,将创建一个包含三个分区(p0,p1,p2)的表:


mysql> USE test;
mysql> CREATE TABLE t1 (i int) ENGINE = InnoDB PARTITION BY KEY (i) PARTITIONS 3;

在/datadir/test目录中,这三个分区中的每一个都有单独的表空间(.ibd)文件。


mysql> \! ls /path/to/datadir/test/
db.opt t1.frm t1#P#p0.ibd t1#P#p1.ibd t1#P#p2.ibd


2.在目标实例,创建相同的分区表:


mysql> USE test;
mysql> CREATE TABLE t1 (i int) ENGINE = InnoDB PARTITION BY KEY (i) PARTITIONS 3;

在/datadir/test目录中,这三个分区中的每一个都有单独的表空间(.ibd)文件。


mysql> \! ls /path/to/datadir/test/
db.opt t1.frm t1#P#p0.ibd t1#P#p1.ibd t1#P#p2.ibd


3.在目标实例上,放弃分区表的表空间。 (在可以在目标实例上导入表空间之前,附加的接收表的表空间必须被丢弃。)


mysql> ALTER TABLE t1 DISCARD TABLESPACE;

构成分区表的表空间的三个.ibd文件将从/datadir/test目录中丢弃,并保留以下文件:


mysql> \! ls /path/to/datadir/test/
db.opt t1.frm


4.在源实例上,运行FLUSH TABLES ... FOR EXPORT以停顿分区表并创建.cfg元数据文件:


mysql> USE test;
mysql> FLUSH TABLES t1 FOR EXPORT;


元数据(.cfg)文件(每个表空间(.ibd)文件一个)在源实例的/datadir/test目录中创建:


mysql> \! ls /path/to/datadir/test/
db.opt t1#P#p0.ibd t1#P#p1.ibd t1#P#p2.ibd t1.frm t1#P#p0.cfg t1#P#p1.cfg t1#P#p2.cfg


注意:


FLUSH TABLES ... FOR EXPORT语句确保对指定表的更改已刷新到磁盘,以便可以在实例运行时创建二进制表副本。 当FLUSH TABLES ... FOR EXPORT运行时,InnoDB为表的表空间文件生成一个.cfg元数据文件,该文件位于与该表相同的数据库目录中。 .cfg文件包含导入表空间文件时用于方案验证的元数据。 FLUSH TABLES ... FOR EXPORT只能在表上运行,而不能在单独的表分区上运行。

5.将.ibd和.cfg文件从源实例数据库目录复制到目标实例数据库目录。 例如:


shell>scp /path/to/datadir/test/t1*.{ibd,cfg} destination-server:/path/to/datadir/test


注意:
如下一步所述,必须在释放共享锁之前复制.ibd和.cfg文件。


6.在源实例上,使用UNLOCK TABLES释放由 FLUSH TABLES ... FOR EXPORT 获取的锁:


mysql> USE test;
mysql> UNLOCK TABLES;


7.在目标实例上,导入分区表的表空间:
mysql> USE test;
mysql> ALTER TABLE t1 IMPORT TABLESPACE;


例子3:将InnoDB表的分区复制到另一个实例


此过程演示如何将InnoDB表分区从正在运行的MySQL服务器实例复制到另一个正在运行的实例。 通过较小的调整,可以使用相同的过程在同一实例上执行InnoDB表分区的恢复。 在以下示例中,将在源实例上创建一个包含四个分区(p0,p1,p2,p3)的分区表。 两个分区(p2和p3)被复制到目标实例。

1.在源实例上,创建一个分区表(如果不存在)。 在以下示例中,将创建一个包含四个分区(p0,p1,p2,p3)的表:


mysql> USE test;
mysql> CREATE TABLE t1 (i int) ENGINE = InnoDB PARTITION BY KEY (i) PARTITIONS 4;


在/datadir/test目录中,四个分区中的每一个都有一个单独的表空间(.ibd)文件。

mysql> \! ls /path/to/datadir/test/
db.opt t1.frm t1#P#p0.ibd t1#P#p1.ibd t1#P#p2.ibd t1#P#p3.ibd




2.在目标实例,创建相同的被分区的表
mysql> USE test;
mysql> CREATE TABLE t1 (i int) ENGINE = InnoDB PARTITION BY KEY (i) PARTITIONS 4;


在/datadir/test目录中,四个分区中的每一个都有一个单独的表空间(.ibd)文件。


mysql> \! ls /path/to/datadir/test/
db.opt t1.frm t1#P#p0.ibd t1#P#p1.ibd t1#P#p2.ibd t1#P#p3.ibd


3.在目标实例上,放弃您计划从源实例导入的表空间分区。 (在可以在目标实例上导入表空间分区之前,附加到接收表的相应分区必须被丢弃。)


mysql> ALTER TABLE t1 DISCARD PARTITION p2, p3 TABLESPACE;


两个丢弃分区的.ibd文件将从目标实例上的/datadir/test目录中删除,并保留以下文件:
mysql> \! ls /path/to/datadir/test/
db.opt t1.frm t1#P#p0.ibd t1#P#p1.ibd


注意:
当ALTER TABLE ... DISCARD PARTITION ... TABLESPACE在子分区表上运行时,分区和子分区表命名都是被允许的。 当指定分区名称时,该分区的子分区将包含在该操作中。

4.在源实例上,运行FLUSH TABLES ... FOR EXPORT以停顿分区表并创建.cfg元数据文件。
mysql> USE test;
mysql> FLUSH TABLES t1 FOR EXPORT;


元数据文件(.cfg文件)在源实例的/ datadir / test目录中创建。 每个表空间(.ibd)文件都有一个.cfg文件。


mysql> \! ls /path/to/datadir/test/
db.opt t1#P#p0.ibd t1#P#p1.ibd t1#P#p2.ibd t1#P#p3.ibd t1.frm t1#P#p0.cfg t1#P#p1.cfg t1#P#p2.cfg t1#P#p3.cfg

注意:


FLUSH TABLES ... FOR EXPORT语句确保对指定表的更改已刷新到磁盘,以便可以在实例运行时创建二进制表副本。 当FLUSH TABLES ... FOR EXPORT运行时,InnoDB为表的表空间文件生成一个.cfg元数据文件,该文件位于与该表相同的数据库目录中。 .cfg文件包含导入表空间文件时用于模式验证的元数据。 FLUSH TABLES ... FOR EXPORT只能在桌面上运行,而不能在单独的桌面分区上运行。


5.将.ibd和.cfg文件从源实例数据库目录复制到目标实例数据库目录。 在此示例中,只有分区2(p2)和分区3(p3)的.ibd和.cfg文件被复制到目标实例上的数据目录。 分区0(p0)和分区1(p1)保留在源实例上。


shell> scp t1#P#p2.ibd t1#P#p2.cfg t1#P#p3.ibd t1#P#p3.cfg destination-server:/path/to/datadir/test


注意:
如下一步所述,在释放共享锁之前,必须复制.ibd文件和.cfg文件。

6.在源实例上,使用UNLOCK TABLES释放由 FLUSH TABLES ... FOR EXPORT 获取的锁:


mysql> USE test;
mysql> UNLOCK TABLES;


7.在目标实例上,导入表空间分区(p2和p3):


mysql> USE test;

mysql> ALTER TABLE t1 IMPORT PARTITION p2, p3 TABLESPACE;

注意:

当ALTER TABLE ... IMPORT PARTITION ... TABLESPACE在子分区表上运行时,分区和子分区表命名都是允许的。 当指定分区名称时,该分区的子分区将包含在该操作中。


14.7.6.2 传输表空间的内部


以下信息描述了InnoDB表的可移植表空间复制过程的内部消息和错误日志消息。

在目标实例上运行ALTER TABLE ... DISCARD TABLESPACE时:

  • 表被 X mode 被锁定
  • 表空间从表上被丢弃

在源实例上运行FLUSH TABLES ... FOR EXPORT时:


  • 在共享模式下刷出为了导出而被锁的表。
  • 清除协调程序线程停止。
  • 脏页面被同步到磁盘。
  • 表元数据被写入二进制.cfg文件。

此操作的预期错误日志消息:


2013-09-24T13:10:19.903526Z 2 [Note] InnoDB: Sync to disk of '"test"."t"' started.

2013-09-24T13:10:19.903586Z 2 [Note] InnoDB: Stopping purge

2013-09-24T13:10:19.903725Z 2 [Note] InnoDB: Writing table metadata to './test/t.cfg'

2013-09-24T13:10:19.904014Z 2 [Note] InnoDB: Table '"test"."t"' flushed to disk


在源实例上运行UNLOCK TABLES时:


  • 二进制.cfg文件被删除
  • 正在导入的一个或多个表上的共享锁被释放,清除协调器线程将重新启动。

预期的日志消息:


2013-09-24T13:10:21.181104Z 2 [Note] InnoDB: Deleting the meta-data file './test/t.cfg'

2013-09-24T13:10:21.181180Z 2 [Note] InnoDB: Resuming purge


当ALTER TABLE ... IMPORT TABLESPACE在目标实例上运行时,导入算法将为每个正在导入的表空间执行以下操作:


  • 检查每个表空间页面是否存在损坏。
  • 每个页面上的空间ID和日志序列号(LSN)都会被更新
  • 标志被验证并且LSN更新为标题页面。
  • Btree页面已更新。
  • 页面状态设置为肮脏,以便将其写入磁盘。


此操作的预期错误日志消息:


2013-07-18 15:15:01 34960 [Note] InnoDB: Importing tablespace for table 'test/t' that was exported from host 'ubuntu'

2013-07-18 15:15:01 34960 [Note] InnoDB: Phase I - Update all pages

2013-07-18 15:15:01 34960 [Note] InnoDB: Sync to disk

2013-07-18 15:15:01 34960 [Note] InnoDB: Sync to disk - done!

2013-07-18 15:15:01 34960 [Note] InnoDB: Phase III - Flush changes to disk

2013-07-18 15:15:01 34960 [Note] InnoDB: Phase IV - Flush complete


注意:

您还可能会收到警告,指出表空间被丢弃(如果您放弃了目标表的表空间)并显示一条消息,指出由于缺少.ibd文件而无法计算统计信息:

2013-07-18 15:14:38 34960 [Warning] InnoDB: Table "test"."t" tablespace is set as discarded.

2013-07-18 15:14:38 7f34d9a37700 InnoDB: cannot calculate statistics for table "test"."t" because the .ibd file is missing.


14.7.7 配置 Undo 表空间


undo日志可能存储在一个或多个undo表空间中,而不是系统表空间中。 此布局与undo日志驻留在系统表空间中的默认配置不同。 undo日志的I / O模式使撤消表空间成为SSD存储的理想候选者,同时将系统表空间保留在硬盘存储上。 undo表空间或这些表空间内的单个分段不能被删除。 但是,可以截断存储在undo表空间中的undo日志。


要为MySQL实例配置单独的undo表空间,请执行以下步骤。 假定您在将配置部署到生产系统之前正在执行测试实例上的过程。


重要:

由于只能在初始化时设置innodb_undo_tablespaces选项,因此只能在初始化新的MySQL实例时配置undo表空间的数量。 指定的设置在MySQL实例的生命周期中是固定的。


注意:

innodb_undo_tablespaces已被弃用,并将在未来版本中删除。


1.使用innodb_undo_directory配置选项指定undo表空间的目录位置。 如果未指定目录位置,则在MySQL数据目录中创建undo表空间。


2.使用innodb_rollback_segments配置选项定义回滚段的数量。 从相对较低的值开始,并逐渐增加以检查对性能的影响。 innodb_rollback_segments的默认设置是128,这也是最大值。

一个回滚段总是分配给系统表空间,32个回滚段为临时表空间(ibtmp1)保留。 因此,要为undo表空间分配回滚段,请将innodb_rollback_segments设置为大于33的值。例如,如果您有两个undo表空间,请将innodb_rollback_segments设置为35,以便为两个撤消表空间中的每个分配一个回滚段。 回滚段以循环方式分布在undo表空间中。


当您配置单独的undo表空间时,系统表空间中的回滚段将呈现为非活动状态。


3.使用innodb_undo_tablespaces选项定义undo表空间的数量。 这个设置在MySQL实例的生命周期中是固定的,所以如果你不确定最优值,评估一个偏高的值。


4.使用您选择的选项值创建一个新的MySQL测试实例。


5.在您的测试实例上使用与您的生产服务器相似的负载来测试配置。


6.基准测试I/O密集型工作负载的性能。


7.定期增加innodb_rollback_segments的值并重新运行性能测试,直到I/O性能没有进一步改进。


14.7.8 截断 undo 表空间


要截断撤消表空间,MySQL实例必须配置至少两个撤消表空间。 至少有两个撤消表空间可确保一个撤消表空间保持活动状态,而另一个撤消表空间则被脱机截断。 undo表空间的数量由innodb_undo_tablespaces选项定义。 缺省值是0.使用此语句检查innodb_undo_tablespaces的值:


mysql> SELECT @@innodb_undo_tablespaces;

+---------------------------+

| @@innodb_undo_tablespaces |

+---------------------------+

| 2 |

+---------------------------+


注意:

innodb_undo_tablespaces已被弃用,并将在未来版本中删除。

要能截断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是一个动态全局变量,默认值为1024 MiB(1073741824字节)。


mysql> SELECT @@innodb_max_undo_log_size;

+----------------------------+

| @@innodb_max_undo_log_size |

+----------------------------+

| 1073741824 |

+----------------------------+


您可以使用SET GLOBAL语句配置innodb_max_undo_log_size:

mysql> SET GLOBAL innodb_max_undo_log_size=2147483648;

当启用innodb_undo_log_truncate时:

1.撤销超过innodb_max_undo_log_size设置的表空间被标记为截断。 选择用于截断的还原表空间是以循环方式执行的,以避免每次都截断同一个还原表空间。


2.驻留在所选undo表空间中的回滚段将变为非活动状态,以便它们不会分配给新事务。 目前正在使用回滚段的现有事务被允许完成。

3.清除系统释放不再需要的回滚段。


4.在undo表空间中的所有回滚段都被释放后,截断操作将运行并且undo表空间将被截断为其初始大小。undo表空间文件的初始大小取决于innodb_page_size值。 对于默认的16k InnoDB页面大小,初始undo表空间文件大小为10MiB。 对于4k,8k,32k和64k页大小,初始undo表空间文件大小分别为7MiB,8MiB,20MiB和40MiB。


截断操作后undo表空间的大小可能会大于初始大小,因为操作完成后会立即使用。


innodb_undo_directory选项定义了撤消表空间文件的位置。 默认值'.'表示默认情况下InnoDB创建其他日志文件的目录。


mysql> SELECT @@innodb_undo_directory;

+-------------------------+

| @@innodb_undo_directory |

+-------------------------+

| . |

+-------------------------+


5.回滚段被重新激活,以便它们可以分配给新的事务。


加快撤销表空间文件的截断


undo表空间不能被截断,直到其回退段被释放。 要加快撤消表空间的截断,请使用innodb_purge_rseg_truncate_frequency选项临时增加清除系统释放回滚段的频率。 缺省innodb_purge_rseg_truncate_frequency设置为128,这也是最大值。


mysql> SELECT @@innodb_purge_rseg_truncate_frequency;

+----------------------------------------+

| @@innodb_purge_rseg_truncate_frequency |

+----------------------------------------+

| 128 |

+----------------------------------------+


要提高清除线程释放回滚段的频率,请减少innodb_purge_rseg_truncate_frequency的值。 例如:


mysql> SET GLOBAL innodb_purge_rseg_truncate_frequency=32;


在线截断undo表空间文件的性能影响


undo表空间被截断时,该表空间中的回滚段将暂时停用。 其他undo表空间中剩余的活动回滚段承担整个系统负载的责任,这可能会导致性能下降。 性能下降的程度取决于许多因素,包括:


  • undo表空间的数量
  • undo日志的数量
  • undo表空间大小
  • I/O susbsystem的速度
  • 现有长时间运行的事务
  • 系统负载

来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/69946831/viewspace-3134194/ ,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论

注册时间:2019-09-09

  • 博文量
    2646
  • 访问量
    42182