Documentation Home
MySQL 8.4 Reference Manual
Related Documentation Download this Manual
PDF (US Ltr) - 39.8Mb
PDF (A4) - 39.9Mb
Man Pages (TGZ) - 257.9Kb
Man Pages (Zip) - 364.9Kb
Info (Gzip) - 4.0Mb
Info (Zip) - 4.0Mb


17.6.3.4 Undo 表空间

Undo 表空间包含undo日志,这些日志是记录,包含了关于如何撤销事务对聚簇索引记录的最新更改的信息。

Undo 表空间在本节中以下主题下进行描述:

默认Undo 表空间

MySQL 实例初始化时创建了两个默认的回滚表空间。默认回滚表空间在初始化时间创建,以提供 rollback 部分的位置,这些部分必须存在于 SQL 语句被接受前。为了支持自动截断回滚表空间,至少需要两个回滚表空间。请参阅截断回滚表空间

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

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

Undo 表pace Size

初始回滚表空间大小通常为16MiB。初始大小可能会在通过truncate操作创建新undo表空间时发生变化。在这种情况下,如果文件扩展大小大于16MB,并且前一个文件扩展发生在最后一秒内,新的undo表空间将被创建到由innodb_max_undo_log_size变量定义的四分之一大小。

undo表空间将被扩展到最小16MB。为了处理激进增长,文件扩展大小将被 doubled,如果前一个文件扩展发生在0.1秒内之前。 doubling扩展大小可以多次发生,直到256MB。如果前一个文件扩展发生在0.1秒以上,则扩展大小将被减半,这也可以多次发生,直到最小16MB。如果undo表空间定义了AUTOEXTEND_SIZE选项,它将被扩展到由该选项设置的值和上述逻辑确定的扩展大小之间的最大值。关于AUTOEXTEND_SIZE选项的信息,请见第17.6.3.9节,“Tablespace AUTOEXTEND_SIZE Configuration”

添加Undo表空间

由于undo日志在长时间事务中可能会变得很大,创建额外的undo表空间可以帮助防止单个undo表空间变得太大。额外的undo表空间可以在运行时使用CREATE UNDO TABLESPACE语法创建。

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

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

Note

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

启动时,innodb_directories变量定义的目录将被扫描以查找undo 表空间文件。 (扫描也会遍历子目录。)无论innodb_data_home_dirinnodb_undo_directorydatadir变量是否被定义,innodb_directories值将自动追加到其中的路径中。因此,无论哪个变量是定义的,undo 表空间文件都可以位于由这些变量定义的路径中。

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

Note

InnoDB恢复过程需要undo表空间文件位于已知目录中。undo表空间文件必须在redo恢复和其他数据文件打开之前被发现和打开,以便回滚未提交事务和数据字典更改。如果在恢复前找不到一个undo表空间,它将无法使用,这可能会导致数据库不一致。在启动时,如果数据字典知道的undo表空间找不到,错误信息将报告。该已知目录要求也支持undo表空间的可移植性。请参阅Moving Undo Tablespaces

要在数据目录相对路径下创建undo表空间,设置innodb_undo_directory变量为相对路径,然后在创建undo表空间时只指定文件名。

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

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

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

可以使用DROP UNDO 表空间语法来删除undo表空间。请参阅删除Undo 表空间

删除Undo 表空间

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

要删除undo表空间,必须先将其标记为 inactive 使用ALTER UNDO 表空间语法,以便表空间不再用于分配回滚段给新事务。

ALTER UNDO TABLESPACE tablespace_name SET INACTIVE;

在undo表空间被标记为 inactive 之后,当前使用回滚段的事务允许完成,同时也允许已经开始的事务继续执行。事务完成后,purge系统释放undo表空间中的回滚段,并将undo表空间截断到初始大小。 (截断undo表空间的过程与删除undo表空间相同。请参阅截断Undo 表空间。) 一旦undo表空间为空,可以删除它。

DROP UNDO TABLESPACE tablespace_name;
Note

另外,可以将undo表空间留在空状态,然后在需要时重新激活它,使用以下语句:ALTER UNDO TABLESPACE tablespace_name SET ACTIVE

可以通过查询信息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表空间将返回错误。

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

移动 Undo 表空间

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

MySQL 实例初始化时创建的默认回滚表空间(innodb_undo_001innodb_undo_002)必须位于由 innodb_undo_目录 变量定义的目录中。如果 innodb_undo_目录 变量未定义,default undo tablespaces 将位于数据目录中。如果在服务器离线时移动 default undo tablespaces,服务器必须在启动时将 innodb_undo_目录 变量配置为新目录。

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

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

默认情况下,innodb_rollback_segments 的设置为 128,这也是最大值。关于回滚段支持的事务数量的信息,请参阅第17.6.6节,“Undo Logs”

截断 Undo 表空间

有两种方法可以截断 Undo 表空间,可以单独使用或组合使用以管理 Undo 表空间大小。其中一种方法是自动的,通过配置变量启用。另一种方法是手动的,使用 SQL 语句进行。

自动截断方法不需要监控 Undo 表空间大小,一旦启用,它将在无需人工干预的情况下对 Undo 表空间进行停用、截断和重新激活。手动截断方法可能是首选,如果您想控制何时对 Undo 表空间进行停用以截断。例如,您可能想要避免在高负载时间段内对 Undo 表空间进行截断。

Automated Truncation

自动截断 Undo 表空间需要至少两个活动的 Undo 表空间,这样可以确保一个 Undo 表空间保持活动状态,而另一个 Undo 表空间被停用以进行截断。默认情况下,MySQL 实例初始化时创建了两个 Undo 表空间。

要使 Undo 表空间自动截断,请启用innodb_undo_log_truncate 变量。例如:

mysql> SET GLOBAL innodb_undo_log_truncate=ON;

innodb_undo_log_truncate变量启用时,undo表空间超过由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. 默认和用户定义的undo表空间超过innodb_max_undo_log_size设置的大小将被标记为截断。选择截断undo表空间的顺序是循环进行的,以避免每次都截断同一个undo表空间。

  2. 在选定的undo表空间中驻留的回滚段将被置为不活动状态,以便它们不能分配给新的事务。当前正在使用回滚段的事务允许完成。

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

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

    截断操作完成后,undo表空间的大小可能会大于初始大小,因为是由于紧急使用导致的。

    变量innodb_undo_目录定义了默认回滚表空间文件的位置。如果变量innodb_undo_目录未定义,默认回滚表空间文件位于数据目录。所有回滚表空间文件,包括使用CREATE UNDO TABLESPACE语法创建的用户定义回滚表空间,可以通过查询信息_schemaFILES表来确定其位置:

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

Manual Truncation

手动截断undo表空间需要至少三个活动的undo表空间。总是需要两个活动的undo表空间来支持可能启用的自动截断。三个undo表空间满足这个要求,同时允许一个undo表空间被手动下线。

要手动启动undo表空间的截断,请先停用undo表空间,执行以下语句:

ALTER UNDO TABLESPACE tablespace_name SET INACTIVE;

在undo表空间标记为 inactive 之后,当前使用回滚段的事务允许完成,同时也允许在那些事务完成之前开始的事务。事务完成后,purge系统释放undo表空间中的回滚段,undo表空间被截断到初始大小,undo表空间状态从inactive变为empty

Note

当执行ALTER UNDO TABLESPACE tablespace_name SET INACTIVE语句时,undo 表空间将被停用,purge 线程将在下一个机会中寻找该 undo 表空间。一旦找到并标记为截断,purge 线程将以更高的频率返回,以快速清空和截断 undo 表空间。

要检查undo 表空间的状态,可以查询信息_schema中的INNODB_TABLESPACES表。

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

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

ALTER UNDO TABLESPACE tablespace_name SET ACTIVE;

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

Expediting Automated Truncation of Undo Tablespaces

purge 线程负责清空和截断 undo 表空间。默认情况下,purge 线程每次被调用128次后才寻找 undo 表空间以截断。purge 线程寻找 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设置。例如,要使purge线程每次调用purge时查找undo tablespaces32次,设置innodb_purge_rseg_truncate_frequency为32。

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

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

  • undo tablespaces的数量

  • undo logs的数量

  • undo tablespace的大小

  • I/O子系统的速度

  • 存在的长时间事务

  • 系统负载

避免性能影响的最简单方法是增加undo tablespaces的数量。

Monitoring Undo Tablespace Truncation

undopurge子系统计数器用于监控undo log截断相关的背景活动。要查询计数器名称和描述,可以查询信息SchemaINNODB_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表空间执行truncate操作的次数限制为64次。该限制可以防止由于innodb_max_undo_log_size设置太低在繁忙系统上出现的问题。如果超出限制,undo表空间仍然可以被标记为 inactive,但直到下一个检查点才会被truncate。在 MySQL 8.4 中,该限制为50000。

Undo Tablespace Truncation Recovery

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

Undo 表pace 状态变量

以下状态变量允许跟踪总共的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节,“服务器状态变量”