暂无图片
暂无图片
2
暂无图片
暂无图片
1
暂无图片

[ACDU 翻译] MySQL 15.6.3.4 撤消表空间

原创 由迪 2022-02-17
605

撤消表空间包含撤消日志,它们是记录的集合,其中包含有关如何撤消事务对聚集索引记录的最新更改的信息。

撤消表空间在本节的以下主题中进行了描述:

默认撤消表空间

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

innodb_undo_directory 默认撤消表空间是在变量 定义的位置创建的。如果 innodb_undo_directory变量未定义,则在数据目录中创建默认撤消表空间。默认撤消表空间数据文件被命名为 undo_001undo_002. 数据字典中定义的相应撤消表空间名称是innodb_undo_001innodb_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_dirinnodb_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_001innodb_undo_002) 无法删除。但是,可以使用 语句将它们设为非活动状态。在默认撤消表空间可以变为非活动状态之前,必须有一个撤消表空间来代替它。始终需要至少两个活动的撤消表空间来支持撤消表空间的自动截断。 ALTER UNDO TABLESPACE *tablespace_name* SET INACTIVE

移动撤消表空间

CREATE UNDO TABLESPACE当服务器离线时,可以将 使用语法创建的撤消表空间 移动到任何已知目录。已知目录是由 innodb_directories变量定义的目录。由 innodb_data_home_dirinnodb_undo_directory和 定义的目录datadir会自动附加到 innodb_directories值中,而不管 innodb_directories变量是否被显式定义。这些目录及其子目录在启动时被扫描以查找撤消表空间文件。移动到这些目录中的任何一个的撤消表空间文件在启动时被发现并假定为被移动的撤消表空间。

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

撤消日志的 I/O 模式使撤消表空间成为SSD存储 的理想选择。

配置回滚段数

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

默认设置为 innodb_rollback_segments128,这也是最大值。有关回滚段支持的事务数的信息,请参阅 第 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 启用变量 时 :

  1. 超出 innodb_max_undo_log_size 设置的默认和用户定义的撤消表空间被标记为截断。以循环方式选择用于截断的撤消表空间,以避免每次都截断相同的撤消表空间。

  2. 驻留在选定撤消表空间中的回滚段变为非活动状态,因此它们不会分配给新事务。当前正在使用回滚段的现有事务被允许完成。

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

  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. 回滚段被重新激活,以便可以将它们分配给新事务。

手动截断

撤消表空间的手动截断至少需要三个活动撤消表空间。始终需要两个活动的撤消表空间来支持启用自动截断的可能性。至少三个撤消表空间满足此要求,同时允许手动使撤消表空间脱机。

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

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.loginnodb_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 节,“服务器状态变量”

「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论

墨天轮福利君
暂无图片
3年前
评论
暂无图片 0
您好,您的文章已入选合格奖,10墨值奖励已经到账请查收! ❤️我们还会实时派发您的流量收益。
3年前
暂无图片 点赞
评论
由迪
暂无图片
关注
暂无图片
获得了298次点赞
暂无图片
内容获得217次评论
暂无图片
获得了344次收藏
TA的专栏
目录
  • 默认撤消表空间
  • 撤消表空间大小
  • 添加撤消表空间
  • 删除撤消表空间
  • 移动撤消表空间
  • 配置回滚段数
  • 截断撤消表空间
    • 自动截断
    • 手动截断
    • 加快撤消表空间的自动截断
    • 截断撤消表空间文件的性能影响
    • 监控撤消表空间截断
    • 撤消表空间截断限制
    • 撤消表空间截断恢复
  • 撤消表空间状态变量