撤消表空间包含撤消日志,它们是记录的集合,其中包含有关如何撤消事务对聚集索引记录的最新更改的信息。
撤消表空间在本节的以下主题中进行了描述:
默认撤消表空间
MySQL 实例初始化时会创建两个默认的 undo 表空间。默认撤消表空间是在初始化时创建的,以便为在接受 SQL 语句之前必须存在的回滚段提供位置。至少需要两个撤消表空间来支持撤消表空间的自动截断。请参阅 截断撤消表空间。
innodb_undo_directory
默认撤消表空间是在变量 定义的位置创建的。如果 innodb_undo_directory
变量未定义,则在数据目录中创建默认撤消表空间。默认撤消表空间数据文件被命名为 undo_001
和undo_002
. 数据字典中定义的相应撤消表空间名称是innodb_undo_001
和 innodb_undo_002
。
从 MySQL 8.0.14 开始,可以在运行时使用 SQL 创建额外的撤消表空间。请参阅 添加撤消表空间。
撤消表空间大小
在 MySQL 8.0.23 之前,撤消表空间的初始大小取决于该innodb_page_size
值。对于默认的 16KB 页大小,初始撤消表空间文件大小为 10MiB。对于 4KB、8KB、32KB 和 64KB 页面大小,初始撤消表空间文件大小分别为 7MiB、8MiB、20MiB 和 40MiB。从 MySQL 8.0.23 开始,初始撤消表空间大小通常为 16MiB。当通过截断操作创建新的撤消表空间时,初始大小可能会有所不同。在这种情况下,如果文件扩展名大于 16MB,并且前一个文件扩展名发生在最后一秒内,则新的 undo 表空间将以 innodb_max_undo_log_size
变量定义的大小的四分之一创建。
在 MySQL 8.0.23 之前,撤消表空间一次扩展四个范围。从 MySQL 8.0.23 开始,撤消表空间至少扩展了 16MB。为了处理激进的增长,如果先前的文件扩展名发生在不到 0.1 秒之前,则文件扩展名的大小会加倍。扩展大小可以多次翻倍,最大为 256MB。如果前一个文件扩展名出现的时间早于 0.1 秒,则扩展名大小会减少一半,也可以多次出现,最小为 16MB。如果该 AUTOEXTEND_SIZE
选项是为撤消表空间定义的,它会扩展 AUTOEXTEND_SIZE
设置和扩展大小由上述逻辑确定。有关该AUTOEXTEND_SIZE
选项的信息,请参阅 第 15.6.3.9 节,“表空间 AUTOEXTEND_SIZE 配置”。
添加撤消表空间
由于撤消日志在长时间运行的事务期间会变得很大,因此创建额外的撤消表空间可以帮助防止单个撤消表空间变得太大。从 MySQL 8.0.14 开始,可以在运行时使用 CREATE UNDO TABLESPACE
语法创建额外的 undo 表空间。
CREATE UNDO TABLESPACE tablespace_name ADD DATAFILE 'file_name.ibu';
复制
撤消表空间文件名必须有 .ibu
扩展名。定义撤消表空间文件名时不允许指定相对路径。允许使用完全限定的路径,但路径必须是已知的InnoDB
。已知路径是由 innodb_directories
变量定义的路径。建议使用唯一的撤消表空间文件名,以避免在移动或克隆数据时发生潜在的文件名冲突。
笔记
在复制环境中,源和每个副本都必须有自己的撤消表空间文件目录。将撤消表空间文件的创建复制到公共目录会导致文件名冲突。
启动时, innodb_directories
会扫描由变量定义的目录以查找撤消表空间文件。(扫描还遍历子目录。)由 、 和 变量定义的目录 innodb_data_home_dir
会 innodb_undo_directory
自动 datadir
附加到 innodb_directories
值中,而不管 innodb_directories
变量是否被显式定义。因此,撤消表空间可以驻留在由任何这些变量定义的路径中。
如果撤消表空间文件名不包含路径,则在 innodb_undo_directory
变量定义的目录中创建撤消表空间。如果该变量未定义,则在数据目录中创建撤消表空间。
笔记
InnoDB
恢复过程要求撤消表空间文件驻留在已知目录中 。必须在重做恢复之前和打开其他数据文件之前发现并打开撤消表空间文件,以允许回滚未提交的事务和数据字典更改。无法使用恢复前未找到的撤消表空间,这可能导致数据库不一致。如果未找到数据字典已知的撤消表空间,则会在启动时报告错误消息。已知目录要求还支持撤消表空间可移植性。请参阅 移动撤消表空间。
要在相对于数据目录的路径中创建撤消表空间,请将 innodb_undo_directory
变量设置为相对路径,并仅在创建撤消表空间时指定文件名。
要查看撤消表空间名称和路径,请查询 INFORMATION_SCHEMA.FILES
:
SELECT TABLESPACE_NAME, FILE_NAME FROM INFORMATION_SCHEMA.FILES
WHERE FILE_TYPE LIKE 'UNDO LOG';
复制
一个 MySQL 实例最多支持 127 个 undo 表空间,包括 MySQL 实例初始化时创建的两个默认 undo 表空间。
笔记
在 MySQL 8.0.14 之前,通过配置 innodb_undo_tablespaces
启动变量来创建额外的 undo 表空间。自 MySQL 8.0.14 起,此变量已弃用且不再可配置。
在 MySQL 8.0.14 之前,增加 innodb_undo_tablespaces
设置会创建指定数量的撤消表空间并将它们添加到活动撤消表空间列表中。减小innodb_undo_tablespaces
设置会从活动撤消表空间列表中删除撤消表空间。从活动列表中删除的撤消表空间保持活动状态,直到现有事务不再使用它们。该 innodb_undo_tablespaces
变量可以在运行时使用 SET
语句配置或在配置文件中定义。
在 MySQL 8.0.14 之前,无法删除停用的撤消表空间。缓慢关闭后可以手动删除撤消表空间文件,但不建议这样做,因为如果关闭服务器时存在打开的事务,则在服务器重新启动后的一段时间内,停用的撤消表空间可能包含活动的撤消日志。从 MySQL 8.0.14 开始,可以使用 DROP UNDO TABALESPACE
语法删除撤消表空间。请参阅 删除撤消表空间。
删除撤消表空间
从 MySQL 8.0.14 开始,使用 CREATE UNDO TABLESPACE
语法创建的撤消表空间可以在运行时使用 DROP UNDO TABALESPACE
语法删除。
撤消表空间必须为空才能被删除。要清空撤消表空间,必须首先使用 ALTER UNDO TABLESPACE
语法将撤消表空间标记为非活动,以便该表空间不再用于将回滚段分配给新事务。
ALTER UNDO TABLESPACE tablespace_name SET INACTIVE;
复制
在撤消表空间被标记为非活动后,当前在撤消表空间中使用回滚段的事务被允许完成,在这些事务完成之前启动的任何事务也是如此。事务完成后,清除系统释放撤消表空间中的回滚段,撤消表空间被截断为其初始大小。(在截断撤消表空间时使用相同的过程。请参阅截断撤消表空间。)一旦撤消表空间为空,就可以删除它。
DROP UNDO TABLESPACE tablespace_name;
复制
笔记
或者,可以将撤消表空间保留为空状态,并在需要时通过发出 语句稍后重新激活。 ALTER UNDO TABLESPACE *
tablespace_name* SET ACTIVE
可以通过查询 INFORMATION_SCHEMA.INNODB_TABLESPACES
表来监控撤消表空间的状态。
SELECT NAME, STATE FROM INFORMATION_SCHEMA.INNODB_TABLESPACES
WHERE NAME LIKE 'tablespace_name';
复制
状态指示撤消表空间中的inactive
回滚段不再被新事务使用。empty
状态指示撤消表空间为空并准备好被删除,或者准备好使用语句再次 激活。尝试删除非空的撤消表空间会返回错误。 ALTER UNDO TABLESPACE *
tablespace_name* SET ACTIVE
初始化 MySQL 实例时创建的默认撤消表空间 (innodb_undo_001
和innodb_undo_002
) 无法删除。但是,可以使用 语句将它们设为非活动状态。在默认撤消表空间可以变为非活动状态之前,必须有一个撤消表空间来代替它。始终需要至少两个活动的撤消表空间来支持撤消表空间的自动截断。 ALTER UNDO TABLESPACE *
tablespace_name* SET INACTIVE
移动撤消表空间
CREATE UNDO TABLESPACE
当服务器离线时,可以将 使用语法创建的撤消表空间 移动到任何已知目录。已知目录是由 innodb_directories
变量定义的目录。由 innodb_data_home_dir
、 innodb_undo_directory
和 定义的目录datadir
会自动附加到 innodb_directories
值中,而不管 innodb_directories
变量是否被显式定义。这些目录及其子目录在启动时被扫描以查找撤消表空间文件。移动到这些目录中的任何一个的撤消表空间文件在启动时被发现并假定为被移动的撤消表空间。
初始化 MySQL 实例时创建的默认撤消表空间 (innodb_undo_001
和innodb_undo_002
) 必须驻留在innodb_undo_directory
变量定义的目录中。如果 innodb_undo_directory
变量未定义,则默认撤消表空间驻留在数据目录中。如果在服务器脱机时移动默认撤消表空间,则必须使用 innodb_undo_directory
配置到新目录的变量启动服务器。
撤消日志的 I/O 模式使撤消表空间成为SSD存储 的理想选择。
配置回滚段数
该innodb_rollback_segments
变量定义 分配给每个撤消表空间和全局临时表空间的回滚段数。该 innodb_rollback_segments
变量可以在启动时或服务器运行时进行配置。
默认设置为 innodb_rollback_segments
128,这也是最大值。有关回滚段支持的事务数的信息,请参阅 第 15.6.6 节,“撤消日志”。
截断撤消表空间
有两种截断撤消表空间的方法,可以单独使用或组合使用来管理撤消表空间大小。一种方法是自动化的,使用配置变量启用。另一种方法是手动的,使用 SQL 语句执行。
自动化方法不需要监控撤消表空间大小,并且一旦启用,它会在无需人工干预的情况下执行撤消表空间的停用、截断和重新激活。如果您想控制撤消表空间何时脱机以进行截断,则手动截断方法可能更可取。例如,您可能希望避免在工作负载高峰期截断撤消表空间。
自动截断
撤消表空间的自动截断至少需要两个活动的撤消表空间,这确保了一个撤消表空间保持活动状态,而另一个撤消表空间被截断。默认情况下,初始化 MySQL 实例时会创建两个 undo 表空间。
要自动截断撤消表空间,请启用该 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
启用变量 时 :
-
超出
innodb_max_undo_log_size
设置的默认和用户定义的撤消表空间被标记为截断。以循环方式选择用于截断的撤消表空间,以避免每次都截断相同的撤消表空间。 -
驻留在选定撤消表空间中的回滚段变为非活动状态,因此它们不会分配给新事务。当前正在使用回滚段的现有事务被允许完成。
-
清除系统通过释放不再使用 的撤消日志来清空回滚段。
-
在撤消表空间中的所有回滚段都被释放后,截断操作运行并将撤消表空间截断为其初始大小。
由于在操作完成后立即使用,截断操作后撤消表空间的大小可能大于初始大小。
该
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';
复制 -
回滚段被重新激活,以便可以将它们分配给新事务。
手动截断
撤消表空间的手动截断至少需要三个活动撤消表空间。始终需要两个活动的撤消表空间来支持启用自动截断的可能性。至少三个撤消表空间满足此要求,同时允许手动使撤消表空间脱机。
要手动启动撤消表空间的截断,请通过发出以下语句停用撤消表空间:
ALTER UNDO TABLESPACE tablespace_name SET INACTIVE;
复制
在撤消表空间被标记为不活动后,当前在撤消表空间中使用回滚段的事务被允许完成,就像在这些事务完成之前启动的任何事务一样。事务完成后,清除系统释放撤消表空间中的回滚段,撤消表空间被截断为其初始大小,撤消表空间状态从 inactive
变为empty
。
笔记
当一条语句停用撤消表空间时,清除线程会在下一次机会时查找该撤消表空间。一旦找到撤消表空间并将其标记为截断,清除线程就会以增加的频率返回以快速清空并截断撤消表空间。 ALTER UNDO TABLESPACE *
tablespace_name* SET INACTIVE
要检查撤消表空间的状态,请查询该 INFORMATION_SCHEMA.INNODB_TABLESPACES
表。
SELECT NAME, STATE FROM INFORMATION_SCHEMA.INNODB_TABLESPACES
WHERE NAME LIKE 'tablespace_name';
复制
一旦撤消表空间处于某种empty
状态,就可以通过发出以下语句重新激活它:
ALTER UNDO TABLESPACE tablespace_name SET ACTIVE;
复制
empty
也可以删除 处于状态的撤消表空间。请参阅删除撤消表空间。
加快撤消表空间的自动截断
清除线程负责清空和截断撤消表空间。默认情况下,清除线程每调用 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
设置。例如,要让清除线程在每 32 次清除被调用时查找一次撤消制表符,设置 innodb_purge_rseg_truncate_frequency
为 32。
mysql> SET GLOBAL innodb_purge_rseg_truncate_frequency=32;
复制
截断撤消表空间文件的性能影响
当撤消表空间被截断时,撤消表空间中的回滚段被停用。其他撤消表空间中的活动回滚段承担整个系统负载的责任,这可能会导致轻微的性能下降。性能受到影响的程度取决于许多因素:
- 撤消表空间的数量
- 撤消日志数
- 撤消表空间大小
- I/O 子系统的速度
- 现有的长期运行的事务
- 系统负载
避免潜在性能影响的最简单方法是增加撤消表空间的数量。
监控撤消表空间截断
从 MySQL 8.0.16 开始,undo
提供 purge
了 susbsystem 计数器来监视与撤消日志截断相关的后台活动。有关计数器名称和说明,请查询该 INFORMATION_SCHEMA.INNODB_METRICS
表。
SELECT NAME, SUBSYSTEM, COMMENT FROM INFORMATION_SCHEMA.INNODB_METRICS WHERE NAME LIKE '%truncate%';
复制
有关启用计数器和查询计数器数据的信息,请参阅 第 15.15.6 节,“InnoDB INFORMATION_SCHEMA Metrics Table”。
撤消表空间截断限制
从 MySQL 8.0.21 开始,检查点之间同一撤消表空间上的截断操作数限制为 64。该限制可防止由于撤消表空间截断操作数过多而导致的潜在问题,如果 innodb_max_undo_log_size
在例如,繁忙的系统。如果超过限制,撤消表空间仍然可以处于非活动状态,但直到下一个检查点之后才会被截断。在 MySQL 8.0.22 中,限制从 64 提高到 50,000。
撤消表空间截断恢复
撤消表空间截断操作会在服务器日志目录中创建一个临时 文件。该日志目录由. 如果在截断操作期间发生系统故障,临时日志文件允许启动进程识别被截断的撤消表空间并继续操作。 undo_*
space_number*_trunc.log
innodb_log_group_home_dir
撤消表空间状态变量
以下状态变量允许跟踪撤消表空间的总数、隐式(InnoDB
-created)撤消表空间、显式(用户创建)撤消表空间和活动撤消表空间的数量:
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 |
+----------------------------------+-------+
复制
有关状态变量的描述,请参阅 第 5.1.10 节,“服务器状态变量”。
文章被以下合辑收录
评论
