重做日志是一种基于磁盘的数据结构,用于在崩溃恢复期间纠正由不完整事务写入的数据。在正常操作期间,重做日志对由 SQL 语句或低级 API 调用产生的更改表数据的请求进行编码。在意外关闭之前未完成更新数据文件的修改会在初始化期间和接受连接之前自动重播。有关重做日志在崩溃恢复中的作用的信息,请参阅 第 15.18.2 节,“InnoDB 恢复”。
默认情况下,重做日志在磁盘上由两个名为ib_logfile0和 的文件物理表示ib_logfile1。MySQL 以循环方式写入重做日志文件。重做日志中的数据根据受影响的记录进行编码;这些数据统称为重做。数据通过重做日志的过程由不断增加的LSN值表示。
与重做日志相关的信息和过程在本节中的以下主题下进行了描述:
更改重做日志文件的数量或大小
要更改重做日志文件 的数量或大小 ,请执行以下步骤:
- 停止 MySQL 服务器并确保它在没有错误的情况下关闭。
- 编辑
my.cnf以更改日志文件配置。要更改日志文件大小,请配置innodb_log_file_size. 要增加日志文件的数量,请配置innodb_log_files_in_group. - 再次启动 MySQL 服务器。
如果InnoDB检测到 innodb_log_file_size与重做日志文件大小不同,它会写入一个日志检查点,关闭并删除旧的日志文件,以请求的大小创建新的日志文件,并打开新的日志文件。
重做日志刷新的组提交
InnoDB与任何其他 符合 ACID的数据库引擎一样,在提交事务之前刷新事务的重做日志。InnoDB 使用组提交 功能将多个刷新请求组合在一起,以避免每次提交都刷新一次。使用组提交, InnoDB向日志文件发出单次写入,以对几乎同时提交的多个用户事务执行提交操作,从而显着提高吞吐量。
重做日志归档
复制重做日志记录的备份实用程序有时可能无法在备份操作进行时跟上重做日志的生成速度,从而导致由于这些记录被覆盖而丢失重做日志记录。当备份操作期间有大量 MySQL 服务器活动,并且重做日志文件存储介质以比备份存储介质更快的速度运行时,通常会出现此问题。MySQL 8.0.17 中引入的重做日志归档功能通过将重做日志记录顺序写入归档文件和重做日志文件来解决此问题。备份实用程序可以根据需要从归档文件中复制重做日志记录,从而避免潜在的数据丢失。
如果在服务器上配置了重做日志归档,则 MySQL Enterprise Backup提供的 MySQL Enterprise Backup将在备份 MySQL 服务器时使用重做日志归档功能。
在服务器上启用重做日志归档需要为 innodb_redo_log_archive_dirs 系统变量设置一个值。该值被指定为以分号分隔的标记重做日志归档目录列表。该 *label:directory* 对由冒号 ( :) 分隔。例如:
mysql> SET GLOBAL innodb_redo_log_archive_dirs='label1:directory_path1[;label2:directory_path2;…]';
这*label是存档目录的任意标识符。它可以是任何字符串,但不允许使用冒号 (😃。也允许使用空标签,但在这种情况下仍需要冒号 (😃。directory_path*必须指定A。 激活重做日志归档时,为重做日志归档文件选择的目录必须存在,否则返回错误。路径可以包含冒号 (’:’),但不允许使用分号 (😉。
必须先配置该 innodb_redo_log_archive_dirs 变量,然后才能激活重做日志归档。默认值为NULL,不允许激活重做日志归档。
笔记
您指定的归档目录必须满足以下要求。(激活重做日志归档时会强制执行这些要求。):
-
目录必须存在。目录不是由重做日志归档进程创建的。否则,将返回以下错误:
ERROR 3844 (HY000): 重做日志归档目录 ’
directory_path1’ 不存在或不是目录 -
目录不能是全世界可访问的。这是为了防止重做日志数据暴露给系统上未经授权的用户。否则,将返回以下错误:
错误 3846 (HY000)😗
directory_path1*所有操作系统用户都可以访问重做日志存档目录“” -
目录不能是由
datadir,innodb_data_home_dir,innodb_directories,innodb_log_group_home_dir,innodb_temp_tablespaces_dir, 或 定义的目录,也不能是这些目录的父目录或子目录。否则,会返回类似以下的错误:innodb_tmpdirinnodb_undo_directorysecure_file_priv错误 3845 (HY000):重做日志存档目录“
directory_path1”在服务器目录“datadir”中、下方或上方 -“/path/to/data_directory”
当支持重做日志归档的备份实用程序启动备份时,备份实用程序通过调用该innodb_redo_log_archive_start() 函数来激活重做日志归档。
如果您没有使用支持重做日志归档的备份实用程序,也可以手动激活重做日志归档,如下所示:
mysql> SELECT innodb_redo_log_archive_start('label', 'subdir');
+------------------------------------------+
| innodb_redo_log_archive_start('label') |
+------------------------------------------+
| 0 |
+------------------------------------------+
要么:
mysql> DO innodb_redo_log_archive_start('label', 'subdir');
Query OK, 0 rows affected (0.09 sec)
笔记
激活重做日志归档(使用 innodb_redo_log_archive_start())的 MySQL 会话必须在归档期间保持打开状态。同一会话必须停用重做日志归档(使用 innodb_redo_log_archive_stop())。如果在显式停用重做日志归档之前终止会话,则服务器会隐式停用重做日志归档并删除重做日志归档文件。
其中*label是由 innodb_redo_log_archive_dirs; 定义的标签 是一个可选参数,用于指定用于保存存档文件subdir的目录的子目录 ;label*它必须是一个简单的目录名称(不允许使用斜杠 (/)、反斜杠 () 或冒号 (😃)。subdir可以为空、null,也可以省略。
只有具有 INNODB_REDO_LOG_ARCHIVE权限的用户才能通过调用激活重做日志归档 innodb_redo_log_archive_start(),或使用 取消激活它 innodb_redo_log_archive_stop()。运行备份实用程序的 MySQL 用户或手动激活和停用重做日志归档的 MySQL 用户必须具有此权限。
重做日志归档文件路径是 ,其中 是由参数 标识的归档目录 。 是用于 的可选参数 。 *directory_identified_by_label*/[*subdir*/]archive.*serverUUID*.000001.log``*directory_identified_by_label*``*label*``innodb_redo_log_archive_start()``*subdir*``innodb_redo_log_archive_start()
例如,重做日志归档文件的完整路径和名称类似于以下内容:
/directory_path/subdirectory/archive.e71a47dc-61f8-11e9-a3cb-080027154b4d.000001.log
备份实用程序完成数据文件的复制后 ,它通过调用该函数 InnoDB停用重做日志归档 。innodb_redo_log_archive_stop()
如果您没有使用支持重做日志归档的备份实用程序,也可以手动停用重做日志归档,如下所示:
mysql> SELECT innodb_redo_log_archive_stop();
+--------------------------------+
| innodb_redo_log_archive_stop() |
+--------------------------------+
| 0 |
+--------------------------------+
要么:
mysql> DO innodb_redo_log_archive_stop();
Query OK, 0 rows affected (0.01 sec)
停止功能成功完成后,备份实用程序从归档文件中查找重做日志数据的相关部分并将其复制到备份中。
在备份实用程序完成复制重做日志数据并且不再需要重做日志归档文件后,它会删除归档文件。
在正常情况下,删除存档文件是备份实用程序的责任。innodb_redo_log_archive_stop()但是,如果重做日志归档操作在调用 之前意外退出 ,MySQL 服务器会删除该文件。
性能注意事项
由于额外的写入活动,激活重做日志归档通常具有较小的性能成本。
在 Unix 和类 Unix 操作系统上,假设没有持续的高更新率,性能影响通常很小。在 Windows 上,假设相同,性能影响通常会更高一些。
如果更新率持续较高,并且重做日志存档文件与重做日志文件位于相同的存储介质上,则由于复合写入活动对性能的影响可能更为显着。
如果更新率持续较高,并且重做日志存档文件位于比重做日志文件慢的存储介质上,则性能会受到任意影响。
写入重做日志归档文件不会妨碍正常的事务日志记录,除非重做日志归档文件存储介质的运行速度比重做日志文件存储介质慢得多,并且有大量的持久重做日志块积压等待写入重做日志归档文件。在这种情况下,事务日志记录速率降低到可以由重做日志归档文件所在的较慢存储介质管理的级别。
禁用重做日志
从 MySQL 8.0.21 开始,您可以使用该 ALTER INSTANCE DISABLE INNODB REDO_LOG语句禁用重做日志记录。此功能旨在将数据加载到新的 MySQL 实例中。禁用重做日志通过避免重做日志写入和双写缓冲来加速数据加载。
警告
此功能仅用于将数据加载到新的 MySQL 实例中。*不要在生产系统上禁用重做日志记录。*在禁用重做日志记录时允许关闭和重新启动服务器,但在禁用重做日志记录时服务器意外停止可能会导致数据丢失和实例损坏。
在禁用重做日志记录时服务器意外停止后尝试重新启动服务器被拒绝,并出现以下错误:
[ERROR] [MY-013598] [InnoDB] Server was killed when Innodb Redo
logging was disabled. Data files could be corrupt. You can try
to restart the database with innodb_force_recovery=6
在这种情况下,初始化一个新的 MySQL 实例并再次启动数据加载过程。
INNODB_REDO_LOG_ENABLE 启用和禁用重做日志记录需要 该权限。
Innodb_redo_log_enabled status 变量允许监视重做日志记录状态 。
禁用重做日志时不允许克隆操作和重做日志归档,反之亦然。
一个ALTER INSTANCE [ENABLE|DISABLE\] INNODB REDO_LOG操作需要一个独占备份元数据锁,它可以防止其他 ALTER INSTANCE操作同时执行。其他ALTER INSTANCE操作必须等待锁释放后才能执行。
以下过程演示了如何在将数据加载到新的 MySQL 实例时禁用重做日志记录。
-
在新的 MySQL 实例上,将
INNODB_REDO_LOG_ENABLE权限授予负责禁用重做日志记录的用户帐户。mysql> GRANT INNODB_REDO_LOG_ENABLE ON *.* to 'data_load_admin'; -
作为
data_load_admin用户,禁用重做日志记录:mysql> ALTER INSTANCE DISABLE INNODB REDO_LOG; -
检查
Innodb_redo_log_enabled状态变量以确保禁用重做日志记录。mysql> SHOW GLOBAL STATUS LIKE 'Innodb_redo_log_enabled'; +-------------------------+-------+ | Variable_name | Value | +-------------------------+-------+ | Innodb_redo_log_enabled | OFF | +-------------------------+-------+ -
运行数据加载操作。
-
作为
data_load_admin用户,在数据加载操作完成后启用重做日志记录:mysql> ALTER INSTANCE ENABLE INNODB REDO_LOG; -
检查
Innodb_redo_log_enabled状态变量以确保启用重做日志记录。mysql> SHOW GLOBAL STATUS LIKE 'Innodb_redo_log_enabled'; +-------------------------+-------+ | Variable_name | Value | +-------------------------+-------+ | Innodb_redo_log_enabled | ON | +-------------------------+-------+




