redo归档概述
在备份操作进行期间,复制redo日志记录的备份应用程序有时可能无法跟上重做日志生成的速度,从而导致由于这些记录被覆盖而丢失redo日志记录。当备份操作期间存在大量 MySQL 服务器活动并且redo日志文件存储介质的运行速度比备份存储介质更快时,最常出现此问题。 MySQL 8.0.17 中引入的redo日志归档功能通过将重做日志记录除了写入redo日志文件之外还依次写入归档文件来解决此问题。备份应用程序可以根据需要从存档文件中复制redo日志记录,从而避免潜在的数据丢失及备份失败问题。
启用归档
在服务器上启用redo日志归档需要为 innodb_redo_log_archive_dirs 系统变量设置一个值。该值被指定为以分号分隔的带标签的redo日志归档目录列表。
内容格式为:label:directory,例如:
mysql> SET GLOBAL innodb_redo_log_archive_dirs='label1:directory_path1[;label2:directory_path2;…]';
复制
label为归档目录的任意标识符。它可以是任何字符串(可以为空,但必须包含冒号),但不允许使用冒号 (😃。。必须指定directory_path。激活redo日志归档时,为redo日志归档文件选择的目录必须存在,否则会返回错误。路径可以包含冒号 (’:’),但不允许使用分号 (😉。
在激活redo日志归档之前,必须配置 innodb_redo_log_archive_dirs 变量。默认值为NULL,不允许激活redo日志归档。
配置redo归档指定的归档目录必须满足以下要求(激活redo日志归档时会强制执行这些要求):
- 目录必须存在。目录不是由重做日志归档进程创建的。否则,返回以下错误:
ERROR 3844 (HY000): Redo log archive directory ‘directory_path1’ does not exist or is not a directory- 目录不能是全局可访问的(权限配置不能太高)。这是为了防止redo日志数据暴露给系统上未经授权的用户。否则,返回以下错误:
ERROR 3846 (HY000): Redo log archive directory ‘directory_path1’ is accessible to all OS users
目录不能是 datadir、innodb_data_home_dir、innodb_directories、innodb_log_group_home_dir、innodb_temp_tablespaces_dir、innodb_tmpdir、innodb_undo_directory 或 secure_file_priv 定义的目录,也不能是这些目录的父目录或子目录。否则会返回类似如下的错误:
ERROR 3845 (HY000): Redo log archive directory ‘directory_path1’ is in, under, or over server directory ‘datadir’ - ‘/path/to/data_directory’
备份使用redo归档
当支持redo日志归档的备份应用程序启动备份时,备份应用程序通过调用 innodb_redo_log_archive_start() 函数来激活redo日志归档。
如果您没有使用支持redo日志归档的备份应用程序,也可以手动激活redo日志归档,如下所示:
mysql> SELECT innodb_redo_log_archive_start('label', 'subdir');
+------------------------------------------+
| innodb_redo_log_archive_start('label') |
+------------------------------------------+
| 0 |
+------------------------------------------+
-- OR
mysql> DO innodb_redo_log_archive_start('label', 'subdir');
Query OK, 0 rows affected (0.09 sec)
复制
注意: 激活redo日志归档(使用 innodb_redo_log_archive_start())的 MySQL 会话必须在归档期间保持打开状态。同一会话必须停用redo日志归档(使用 innodb_redo_log_archive_stop())。如果在显式停用redo日志归档之前终止会话,服务器将隐式停用redo日志归档并删除redo日志归档文件。
其中label是innodb_redo_log_archive_dirs定义的标签; subdir 是一个可选参数,用于指定由label标识的目录的子目录,用于保存存档文件;它必须是一个简单的目录名称(不允许使用斜杠 (/)、反斜杠 () 或冒号 (😃)。 subdir 可以为空、null,也可以省略。
只有具有 INNODB_REDO_LOG_ARCHIVE 权限的用户才能通过调用 innodb_redo_log_archive_start() 激活redo日志归档,或使用 innodb_redo_log_archive_stop() 停用它。运行备份应用程序的 MySQL 用户或手动激活和停用redo日志归档的 MySQL 用户必须具有此权限。
redo日志归档文件路径为directory_identified_by_label/[subdir/]archive.serverUUID.000001.log,其中directory_identified_by_label是由innodb_redo_log_archive_start()的label参数标识的归档目录。 subdir 是用于 innodb_redo_log_archive_start() 的可选参数。
例如,redo日志归档文件的完整路径和名称如下所示:
/directory_path/subdirectory/archive.e71a47dc-61f8-11e9-a3cb-080027154b4d.000001.log
复制
备份应用程序完成 InnoDB 数据文件复制后,它会通过调用 innodb_redo_log_archive_stop() 函数来停用redo日志归档。
如果您没有使用支持redo日志归档的备份应用程序,也可以手动停用redo日志归档,如下所示:
mysql> SELECT innodb_redo_log_archive_stop();
+--------------------------------+
| innodb_redo_log_archive_stop() |
+--------------------------------+
| 0 |
+--------------------------------+
-- OR
mysql> DO innodb_redo_log_archive_stop();
Query OK, 0 rows affected (0.01 sec)
复制
停止功能成功完成后,备份应用程序从存档文件中查找redo日志数据的相关部分并将其复制到备份中。
备份应用程序完成redo日志数据的复制并且不再需要redo日志归档文件后,它将删除该归档文件。
在正常情况下,删除存档文件是备份应用程序的责任。但是,如果redo日志归档操作在调用 innodb_redo_log_archive_stop() 之前意外退出,MySQL 服务器将删除该文件。