撤消表空间
撤消表空间包含撤消日志,撤消日志是撤消日志记录的集合,其中包含有关如何通过事务撤消对聚集索引记录的最新更改的信息。撤消日志存在于撤消日志段中,撤消日志段中包含撤消日志段。该innodb_rollback_segments
变量定义分配给每个撤消表空间的回滚段数。
初始化MySQL实例时,会创建两个默认的撤消表空间。默认的撤消表空间是在初始化时创建的,以提供回滚段的位置,这些段必须存在才能接受SQL语句。至少需要两个撤消表空间才能支持撤消表空间的自动截断。请参见截断撤消表空间。
默认撤消表空间在innodb_undo_directory
变量定义的位置中创建。如果innodb_undo_directory
未定义变量,则在数据目录中创建默认的撤消表空间。默认的撤消表空间数据文件名为undo_001
和undo_002
。数据字典中定义的相应撤消表空间名称为innodb_undo_001
和innodb_undo_002
。
从MySQL 8.0.14开始,可以在运行时使用SQL创建其他撤消表空间。请参阅添加撤消表空间。
撤消表空间数据文件的初始大小取决于该innodb_page_size
值。对于默认的16KB页面大小,初始撤消表空间文件大小为10MiB。对于4KB,8KB,32KB和64KB页面大小,初始撤消表空间文件大小分别为7MiB,8MiB,20MiB和40MiB。
添加撤消表空间
由于在长时间运行的事务中撤消日志可能会很大,因此创建其他撤消表空间可以帮助防止单个撤消表空间变得太大。从MySQL 8.0.14开始,可以在运行时使用CREATE UNDO TABLESPACE
语法创建其他撤消表空间。
CREATE UNDO TABLESPACE tablespace_nameADD DATAFILE 'file_name.ibu';
undo表空间文件名必须具有.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_NAMEFROM INFORMATION_SCHEMA.FILESWHERE FILE_TYPE LIKE 'UNDO LOG';
一个MySQL实例最多支持127个撤消表空间,其中包括在初始化MySQL实例时创建的两个默认撤消表空间。
注意在MySQL 8.0.14之前,通过配置
innodb_undo_tablespaces
启动变量来创建附加的撤消表空间。从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_nameSET INACTIVE ;
将撤消表空间标记为非活动后,允许当前使用撤消表空间中的回滚段的事务完成,以及在这些事务完成之前启动的任何事务。事务完成后,清除系统将释放还原表空间中的回滚段,并且还原表空间将被截断为其初始大小。(截断撤消表空间时使用相同的过程。请参见截断撤消表空间。)当撤消表空间为空时,可以将其删除。
DROP UNDO TABLESPACE tablespace_name;
注意另外,撤消表空间可以保留为空状态,并在以后需要时通过发出一条语句重新激活。
ALTER UNDO TABLESPACE tablespace_name SET ACTIVE
可以通过查询INFORMATION_SCHEMA.INNODB_TABLESPACES
表来监视撤消表空间的状态。
SELECT NAME , STATEFROM INFORMATION_SCHEMA.INNODB_TABLESPACESWHERE NAME LIKE tablespace_name;
一个inactive
状态指示在撤销表空间回滚段不再使用新的交易。一个empty
状态指示UNDO表空间是空的,并准备好被丢弃或再使用作出了积极发言。尝试删除不为空的撤消表空间将返回错误。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,这也是最大值。有关回滚段支持的事务数的信息,请参见“撤消日志”。
截断撤消表空间
截断撤消表空间的方法有两种,可以单独使用或组合使用两种方法来管理撤消表空间的大小。一种方法是自动的,可以使用配置变量启用。另一种方法是手动的,使用SQL语句执行。
自动化方法不需要监视撤消表空间的大小,并且一旦启用,便无需手动干预即可执行撤消表空间的停用,截断和重新激活操作。如果要控制何时撤消撤消表空间以进行截断,则最好使用手动截断方法。例如,您可能要避免在工作负载高峰期间截断撤消表空间。
自动截断
自动截断撤消表空间需要至少两个活动的撤消表空间,以确保一个撤消表空间保持活动状态,而另一个撤消表空间被脱机以被截断。默认情况下,初始化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
启用变量:
- 超出
innodb_max_undo_log_size
设置的默认和用户定义的撤消表空间将标记为被截断。以循环方式选择撤消表空间以进行截断,以避免每次都截断相同的撤消表空间。 - 驻留在选定撤消表空间中的回滚段将变为非活动状态,以便不将其分配给新事务。允许当前正在使用回滚段的现有事务完成。
- 该净化系统的FreeS回滚不再使用的部分。
撤消撤消表空间中的所有回滚段后,将执行截断操作并将撤消表空间截断为其初始大小。撤消表空间的初始大小取决于该
innodb_page_size
值。对于默认的16KB页面大小,初始撤消表空间文件大小为10MiB。对于4KB,8KB,32KB和64KB页面大小,初始撤消表空间文件大小分别为7MiB,8MiB,20MiB和40MiB。截断操作后撤消表空间的大小可能会大于初始大小,这是由于在操作完成后立即使用撤消表空间。
该
innodb_undo_directory
变量定义默认撤消表空间文件的位置。如果innodb_undo_directory
变量未定义,则默认的撤消表空间位于数据目录中。CREATE UNDO TABLESPACE
可以通过查询INFORMATION_SCHEMA.FILES
表来确定所有撤销表空间文件的位置,包括使用语法创建的用户定义的撤销表空间:SELECT TABLESPACE_NAME, FILE_NAMEFROM INFORMATION_SCHEMA.FILESWHERE FILE_TYPE LIKE 'UNDO LOG';- 重新激活回滚段,以便可以将其分配给新事务。
手动截断
手动截断撤消表空间至少需要三个活动的撤消表空间。始终需要两个活动的撤消表空间,以支持启用自动截断的可能性。至少三个撤消表空间满足此要求,同时允许手动撤消撤消表空间。
要手动启动撤消表空间的截断,请通过发出以下语句来停用撤消表空间:
ALTER UNDO TABLESPACE tablespace_nameSET INACTIVE ;
将撤消表空间标记为非活动后,允许当前在撤消表空间中使用回滚段的事务完成,以及在这些事务完成之前启动的任何事务。事务完成后,清除系统将释放还原表空间中的回滚段,还原表空间被截断为其初始大小,并且还原表空间的状态从inactive
变为empty
。
注意当语句取消激活撤消表空间时,清除线程会在下一次机会中查找该撤消表空间。一旦找到撤消表空间并将其标记为被截断,清除线程就会以更高的频率返回以快速清空并截断撤消表空间。
ALTER UNDO TABLESPACE tablespace_name SET INACTIVE
要检查撤消表空间的状态,请查询INFORMATION_SCHEMA.INNODB_TABLESPACES
表。
SELECT NAME , STATEFROM INFORMATION_SCHEMA.INNODB_TABLESPACESWHERE NAME LIKE tablespace_name;
撤消表空间处于empty
状态后,可以通过发出以下语句将其重新激活:
ALTER UNDO TABLESPACE tablespace_nameSET 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次调用清除操作一次查找undo tabespace,将其设置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_METRICSWHERE NAME LIKE '%truncate%';
有关启用计数器和查询计数器数据的信息,请参见“ InnoDB INFORMATION_SCHEMA指标表”。
撤消表空间状态变量
以下状态变量允许跟踪撤消表空间,隐式(InnoDB
创建的)撤消表空间,显式(用户创建的)撤消表空间以及活动撤消表空间的总数:
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 | +---------------------------------- +------- +
有关状态变量的说明,请参见“服务器状态变量”。