Documentation Home
MySQL 8.3 Reference Manual
Related Documentation Download this Manual
PDF (US Ltr) - 40.8Mb
PDF (A4) - 40.9Mb
Man Pages (TGZ) - 294.0Kb
Man Pages (Zip) - 409.0Kb
Info (Gzip) - 4.0Mb
Info (Zip) - 4.0Mb
Excerpts from this Manual

17.6.3.4 撤销表空间

撤销表空间包含撤销日志,撤销日志是包含事务对聚簇索引记录所做的最新更改信息的记录集合。

撤销表空间在本节中描述以下主题:

默认撤销表空间

在 MySQL 实例初始化时创建两个默认撤销表空间。默认撤销表空间是在初始化时创建的,以便提供回滚段的位置,以便在 SQL 语句可以被接受之前。至少需要两个撤销表空间来支持自动截断撤销表空间。请参阅 截断撤销表空间

默认撤销表空间是在 innodb_undo_directory 变量定义的位置创建的。如果 innodb_undo_directory 变量未定义,默认撤销表空间将在数据目录中创建。默认撤销表空间数据文件名为 undo_001undo_002。对应的撤销表空间名称在数据字典中定义为 innodb_undo_001innodb_undo_002

可以在运行时使用 SQL 语句创建额外的撤销表空间。请参阅 添加撤销表空间

撤销表空间大小

撤销表空间的初始大小通常为 16MiB。初始大小可能在 truncate 操作中创建新的撤销表空间时有所不同。在这种情况下,如果文件扩展大小大于 16MB,并且之前的文件扩展发生在最后一秒钟内,则新的撤销表空间将在 innodb_max_undo_log_size 变量定义的大小的四分之一处创建。

撤销表空间扩展的最小大小为 16MB。为了处理激进的增长,如果之前的文件扩展发生在 0.1 秒之前,文件扩展大小将加倍。文件扩展大小的加倍可以多次发生,直到达到 256MB。如果之前的文件扩展发生在 0.1 秒之前,文件扩展大小将减半,直到达到 16MB。如果定义了撤销表空间的 AUTOEXTEND_SIZE 选项,它将扩展到大于 AUTOEXTEND_SIZE 设置和扩展大小的大小。有关 AUTOEXTEND_SIZE 选项的信息,请参阅 第 17.6.3.9 节,「表空间 AUTOEXTEND_SIZE 配置」

添加撤销表空间

因为撤销日志在长时间运行的事务中可能变得很大,因此创建附加的撤销表空间可以帮助防止单个撤销表空间变得太大。可以使用CREATE UNDO TABLESPACE语法在运行时创建附加的撤销表空间。

CREATE UNDO TABLESPACE tablespace_name ADD DATAFILE 'file_name.ibu';

撤销表空间文件名必须具有.ibu扩展名。不允许在定义撤销表空间文件名时指定相对路径。可以指定完全限定路径,但路径必须是InnoDB已知的路径。已知路径是由innodb_directories变量定义的。建议使用唯一的撤销表空间文件名,以避免在移动或克隆数据时可能的文件名冲突。

Note

在复制环境中,源服务器和每个副本必须拥有其自己的撤销表空间文件目录。将撤销表空间文件的创建复制到公共目录将导致文件名冲突。

在启动时,innodb_directories变量定义的目录将被扫描以查找撤销表空间文件。(扫描也将遍历子目录。)innodb_data_home_dirinnodb_undo_directorydatadir变量定义的目录将自动追加到innodb_directories值中,无论innodb_directories变量是否被显式定义。因此,撤销表空间可以驻留在任何这些变量定义的路径中。

如果撤销表空间文件名不包括路径,则撤销表空间将在innodb_undo_directory变量定义的目录中创建。如果该变量未定义,则撤销表空间将在数据目录中创建。

Note

InnoDB恢复过程要求撤销表空间文件驻留在已知目录中。撤销表空间文件必须在redo恢复之前被发现和打开,以便回滚未提交的事务和数据字典更改。如果在恢复之前未找到撤销表空间,可能会导致数据库不一致。在启动时,如果数据字典中已知的撤销表空间未被找到,将报告错误信息。已知目录要求也支持撤销表空间的可移植性。见移动撤销表空间

要在数据目录的相对路径中创建撤销表空间,请将innodb_undo_directory变量设置为相对路径,并在创建撤销表空间时仅指定文件名。

要查看撤销表空间名称和路径,请查询INFORMATION_SCHEMA.FILES

SELECT TABLESPACE_NAME, FILE_NAME FROM INFORMATION_SCHEMA.FILES
  WHERE FILE_TYPE LIKE 'UNDO LOG';

MySQL 实例支持最多 127 个撤销表空间,包括在 MySQL 实例初始化时创建的两个默认撤销表空间。

撤销表空间可以使用DROP UNDO TABALESPACE语法删除。见删除撤销表空间

删除撤销表空间

使用CREATE UNDO TABLESPACE语法创建的撤销表空间可以在运行时使用DROP UNDO TABALESPACE语法删除。

撤销表空间必须为空才能被删除。要清空撤销表空间,首先必须使用ALTER UNDO TABLESPACE语法将其标记为不活动,以便不再将其用于分配回滚段给新事务。

ALTER UNDO TABLESPACE tablespace_name SET INACTIVE;

在undo表空间被标记为非活动状态后,当前使用回滚段的交易将被允许完成,同时也允许在这些交易完成之前启动的交易。完成交易后,清除系统将释放undo表空间中的回滚段,并将undo表空间截断到其初始大小。(同样的过程也适用于截断undo表空间。参见截断Undo Tablespaces。)一旦undo表空间为空,它就可以被删除。

DROP UNDO TABLESPACE tablespace_name;
Note

或者,undo表空间可以保持为空状态,并在需要时重新激活,通过发出ALTER UNDO TABLESPACE tablespace_name SET ACTIVE语句。

可以通过查询Information Schema INNODB_TABLESPACES表来监控undo表空间的状态。

SELECT NAME, STATE FROM INFORMATION_SCHEMA.INNODB_TABLESPACES
  WHERE NAME LIKE 'tablespace_name';

一个inactive状态表明undo表空间中的回滚段不再被新交易使用。一个empty状态表明undo表空间为空并准备好被删除,或者准备好重新激活使用ALTER UNDO TABLESPACE tablespace_name SET ACTIVE语句。尝试删除不为空的undo表空间将返回错误。

默认的undo表空间(innodb_undo_001innodb_undo_002)在MySQL实例初始化时创建不能被删除。它们可以,但是,使用ALTER UNDO TABLESPACE tablespace_name SET INACTIVE语句被标记为非活动状态。在默认的undo表空间被标记为非活动状态之前,必须有一个undo表空间来取代它。至少需要两个活动的undo表空间来支持自动截断undo表空间。

移动Undo Tablespaces

使用CREATE UNDO TABLESPACE语法创建的undo表空间可以在服务器离线时移动到任何已知目录。已知目录是由innodb_directories变量定义的。由innodb_data_home_dirinnodb_undo_directorydatadir定义的目录将自动追加到innodb_directories值中,无论innodb_directories变量是否被明确定义。这些目录及其子目录将在启动时被扫描以查找undo表空间文件。移动到这些目录中的undo表空间文件将在启动时被发现,并被认为是被移动的undo表空间。

默认的undo表空间(innodb_undo_001innodb_undo_002)在MySQL实例初始化时创建必须驻留在innodb_undo_directory变量定义的目录中。如果innodb_undo_directory变量未定义,默认的undo表空间将驻留在数据目录中。如果默认的undo表空间在服务器离线时被移动,服务器必须使用innodb_undo_directory变量配置到新目录时启动。

Undo日志的I/O模式使undo表空间成为SSD存储的良好候选。

配置回滚段的数量

变量 innodb_rollback_segments 定义了每个撤销表空间和全局临时表空间分配的撤销段数。变量 innodb_rollback_segments 可以在启动时或服务器运行时配置。

变量 innodb_rollback_segments 的默认设置为 128,这也是最大值。有关撤销段支持的交易数量的信息,请参阅 第 17.6.6 节,“撤销日志”

截断撤销表空间

有两种截断撤销表空间的方法,可以单独使用或组合使用以管理撤销表空间大小。一个方法是自动化的,使用配置变量启用。另一个方法是手动的,使用 SQL 语句执行。

自动化方法不需要监控撤销表空间大小,一旦启用,就会在不需要手动干预的情况下执行撤销表空间的停用、截断和重新激活。手动截断方法可能更适合您想要控制何时截断撤销表空间的情况。例如,您可能想避免在高峰工作负载期间截断撤销表空间。

Automated Truncation

自动截断撤销表空间需要至少两个活动撤销表空间,这确保了在一个撤销表空间被截断时,另一个撤销表空间保持活动。默认情况下,在 MySQL 实例初始化时创建了两个撤销表空间。

要自动截断撤销表空间,启用变量 innodb_undo_log_truncate。例如:

mysql> SET GLOBAL innodb_undo_log_truncate=ON;

当变量 innodb_undo_log_truncate 启用时,超过大小限制的撤销表空间将被截断,该限制由变量 innodb_max_undo_log_size 定义。变量 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 启用时:

  1. 超过 innodb_max_undo_log_size 设置的默认和用户定义的撤销表空间将被标记为截断。选择撤销表空间以截断是循环进行的,以避免每次截断同一个撤销表空间。

  2. 驻留在所选撤销表空间中的回滚段将被停用,以便不再分配给新事务。当前使用回滚段的现有事务将被允许完成。

  3. purge 系统通过释放不再使用的撤销日志来清空回滚段。

  4. 在所有回滚段被释放后,截断操作将运行并将撤销表空间截断到其初始大小。

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

    变量 innodb_undo_directory 定义了默认撤销表空间文件的位置。如果变量 innodb_undo_directory 未定义,默认撤销表空间将驻留在数据目录中。所有撤销表空间文件的位置,包括使用 CREATE UNDO TABLESPACE 语法创建的用户定义撤销表空间,可以通过查询 Information Schema FILES 表来确定:

    SELECT TABLESPACE_NAME, FILE_NAME FROM INFORMATION_SCHEMA.FILES WHERE FILE_TYPE LIKE 'UNDO LOG';
  5. 回滚段将被重新激活,以便分配给新事务。

Manual Truncation

手动截断撤销表空间需要至少三个活动撤销表空间。两个活动撤销表空间在任何时候都需要支持自动截断的可能性。三个撤销表空间的最小数量满足了这个要求,同时允许撤销表空间被手动截断。

要手动启动撤销表空间的截断,请停用撤销表空间,发出以下语句:

ALTER UNDO TABLESPACE tablespace_name SET INACTIVE;

在undo表空间被标记为非活动状态后,当前使用回滚段的事务被允许完成,同时启动在这些事务完成之前的任何事务。完成事务后,清除系统释放undo表空间中的回滚段,undo表空间被截断到其初始大小,并且undo表空间状态从inactive更改为empty

Note

ALTER UNDO TABLESPACE tablespace_name SET INACTIVE语句停用undo表空间时,清除线程将在下一个机会中查找该undo表空间。找到undo表空间并标记为截断后,清除线程将以增加的频率返回,以快速清空和截断undo表空间。

要检查undo表空间的状态,请查询信息模式INNODB_TABLESPACES表。

SELECT NAME, STATE FROM INFORMATION_SCHEMA.INNODB_TABLESPACES
  WHERE NAME LIKE 'tablespace_name';

一旦undo表空间处于empty状态,就可以通过发出以下语句重新激活它:

ALTER UNDO TABLESPACE tablespace_name SET ACTIVE;

undo表空间在empty状态下也可以被删除。请参阅删除Undo Tablespaces

Expediting Automated Truncation of Undo Tablespaces

清除线程负责清空和截断undo表空间。默认情况下,清除线程每128次调用purge时查找undo表空间以截断。控制清除线程查找undo表空间以截断的频率的变量是innodb_purge_rseg_truncate_frequency,其默认设置为128。

mysql> SELECT @@innodb_purge_rseg_truncate_frequency;
+----------------------------------------+
| @@innodb_purge_rseg_truncate_frequency |
+----------------------------------------+
|                                    128 |
+----------------------------------------+

要增加频率,请减少innodb_purge_rseg_truncate_frequency设置。例如,要使清除线程每32次调用purge时查找undo表空间,请将innodb_purge_rseg_truncate_frequency设置为32。

mysql> SET GLOBAL innodb_purge_rseg_truncate_frequency=32;
Performance Impact of Truncating Undo Tablespace Files

当undo表空间被截断时,undo表空间中的回滚段被停用。其他undo表空间中的活动回滚段承担整个系统负载,这可能会导致轻微的性能下降。性能受到影响的程度取决于多个因素:

  • undo表空间的数量

  • undo日志的数量

  • undo表空间的大小

  • I/O子系统的速度

  • 现有的长时间运行的事务

  • 系统负载

避免潜在性能影响的最简单方法是增加undo表空间的数量。

Monitoring Undo Tablespace Truncation

undopurge子系统计数器提供了监视背景活动相关的undo日志截断的功能。对于计数器名称和描述,请查询信息模式INNODB_METRICS表。

SELECT NAME, SUBSYSTEM, COMMENT FROM INFORMATION_SCHEMA.INNODB_METRICS WHERE NAME LIKE '%truncate%';

有关启用计数器和查询计数器数据的信息,请参阅第17.15.6节,“InnoDB INFORMATION_SCHEMA Metrics Table”

Undo Tablespace Truncation Limit

在检查点之间对同一个undo表空间的截断操作的次数限制为64。该限制防止了可能由于innodb_max_undo_log_size设置太低而导致的undo表空间截断操作过多的问题,例如。在MySQL 8.3中,该限制为50000。

Undo Tablespace Truncation Recovery

undo表空间截断操作创建了一个临时undo_space_number_trunc.log文件在服务器日志目录中。该日志目录由innodb_log_group_home_dir定义。如果在截断操作期间发生系统故障,该临时日志文件允许启动过程识别undo表空间并继续操作。

Undo表空间状态变量

以下状态变量允许跟踪undo表空间的总数、隐式(InnoDB创建的)undo表空间、显式(用户创建的)undo表空间和活动undo表空间的数量:

mysql> SHOW STATUS LIKE 'Innodb_undo_tablespaces%';
+----------------------------------+-------+
| Variable_name                    | Value |
+----------------------------------+-------+
| Innodb_undo_tablespaces_total    | 2     |
| Innodb_undo_tablespaces_implicit | 2     |
| Innodb_undo_tablespaces_explicit | 0     |
| Innodb_undo_tablespaces_active   | 2     |
+----------------------------------+-------+

有关状态变量描述,请参阅 第 7.1.10 节,“服务器状态变量”