MySQL8.0.30中redo log的变化

MySQL8.0.30 redo log 动态调整

MySQL redo log记录数据记录变更,以及未数据一致性恢复提供保障。在运维MySQL 过程中,会遇到调整redo log 和redo buffer size 大小的需求,然而修改redo log 文件大小需要重启,不过 MySQL 8.0.30 版本中提供动态调整redo log 文件大小的功能。

https://dev.mysql.com/doc/refman/8.0/en/innodb-parameters.html

从 MySQL 8.0.30 开始, innodb_redo_log_capacity系统变量控制 redo log 总的大小。

因为在该版本以及之后的版本参数innodb_log_file_size 和 innodb_log_files_in_group 已经被废弃。

如下图所示,8.0.30 版本对原来的循环覆盖写的结构进行了改造,不再以 redo 文件个数和单个 redo 文件的大小来进行限制,而是通过 innodb_redo_log_capacity来指定整个 redo 空间的大小。整个redo空间会被切成32个文件(固定个数),文件按照 ib_redo$SEQ 的方式进行编号,$SEQ 是一个递增的序列号。在文件管理上,所有的文件会被分成两类:

  • normal redo 文件,命名为 ib_redo$SEQ,正常的 redo 文件,和以前一样,任意时刻只会有一个 redo 文件进行写入;
  • unused redo 文件,命名为 ib_redo$SEQ_tmp,未被使用的 redo 文件在被使用时,会被重命名为正常文件;

后台的 log_files_governor 线程会负责处理已经写完成的文件,在满足回收条件时,会重新变成 unused redo 文件

当 innodb_redo_log_capacity 发生变化时,已经使用过的和正在使用过的 redo 文件并不会发生改变,仅需要调整 unused redo 文件。当用户修改 innodb_redo_log_capacity 时,会唤醒后台的 log_files_governor 线程,后台线程首先会重新计算当前的 redo_log_capacity,然后根据变化的类型:

  • 如果是空间放大,直接根据放大后的大小,重新生成新的 unused redo 文件;
  • 如果是空间缩小,需要计算当前已使用的空间数能否满足目标值,如果满足,那么缩小过程和放大过程一样,直接重新生成新的 ununsed redo 文件即可;如果不能,还需要在更新 redo_log_capacity 之后,通过调整暴露给 log_writer 和 page_cleaner 线程的 lsn 信息,来加速空间回收;

unused redo 文件的引入,类似于引入了缓存区的机制,因为 unused redo 文件不是正在使用的 redo 文件,所以可以直接进行重建,从而满足 innodb_redo_log_capacity 的设置。

在运行时设置时,配置更改会立即发生,但可能需要一些时间才能完全实现新的限制。如果重做日志文件占用的空间小于指定值,则脏页将从缓冲池中较不积极地刷新到表空间数据文件中,最终增加重做日志文件所占用的磁盘空间。如果重做日志文件占用的空间超过指定值,则会更积极地刷新脏页,最终减少重做日志文件所占用的磁盘空间。

https://dev.mysql.com/doc/refman/8.0/en/innodb-redo-log.html

MySQL 8.0.17 redo log归档

在需要备份重做日志以满足审计合规要求、进行数据库维护升级或迁移、以及在高负载系统中减少磁盘 I/O 操作对性能影响的情况下特别有用。归档操作应在系统负载较低时进行,并且需要确保归档目录的安全性和正确配置。

在启用 redo log 归档之前,需要创建一个或多个目录来存储归档的 redo log,确保运行 mysqld的系统用户拥有该目录的访问权限。

1
2
3
mkdir -p /var/lib/mysql-redo-archive/backup1
chown -R mysql.mysql /var/lib/mysql-redo-archive
chmod -R 700 /var/lib/mysql-redo-archive/

使用 innodb_redo_log_archive_dirs 全局变量定义标记的归档路径,或者在配置文件种配置,格式为 label:directory-path,可以使用分号分隔多个条目。

1
set global innodb_redo_log_archive_dirs='backup1:/var/lib/mysql-redo-archive/';

1
show variables like 'innodb_redo_log_archive_dirs';

启动和停止归档,具有 innodb_redo_log_archive 权限的用户可以调用 innodb_redo_log_archive_start() 或 innodb_redo_log_archive_stop() 函数来启动或停止归档。

启动

1
2
3
do innodb_redo_log_archive_start('backup1', 'backup1'); 
or
select innodb_redo_log_archive_start('backup1', 'backup1');

停止

1
2
3
do innodb_redo_log_archive_stop();   
or
select innodb_redo_log_archive_stop();

MySQL 8.0.16 redo log加密

MySQL 8.0.16版本以后可以使用innodb_redo_log_encrypt配置选项启用了Redo日志数据加密。默认情况下,Redo日志加密是禁用的。与表空间数据一样,Redo日志数据加密是在将数据写入磁盘时进行的,而解密是在从磁盘读取重做日志数据时进行的。一旦数据读入内存,它就处于未加密形式。使用表空间加密密钥对重做日志数据进行加密和解密。

启用innodb_redo_log_encrypt时,磁盘上存在的未加密Redo日志页面将保持未加密状态,新的Redo日志页面将以加密形式写入磁盘。同样,禁用innodb_redo_log_encrypt时,磁盘上存在的已加密Redo日志页面将保持加密状态,新的Redo日志页面将以未加密形式写入磁盘。

https://dev.mysql.com/doc/refman/8.0/en/innodb-parameters.html

1
SET GLOBAL default_table_encryption=ON;

MySQL 8.0.21 redo log禁用

MySQL 8.0.21版本之后可以启禁用Redo log功能。可以通过避免写入Redo和doublewrite缓冲来加快数据加载。一般初期大量灌入数据是采用。平时就不建议使用此功能,意外发生 或 服务停止可能会导致数据丢失和实例损坏。

启禁用需要有INNODB_REDO_LOG_ENABLE权限

1
2
3
4
5
#启用
ALTER INSTANCE ENABLE INNODB REDO_LOG;
SHOW GLOBAL STATUS LIKE 'Innodb_redo_log_enabled';
#禁用
ALTER INSTANCE DISABLE INNODB REDO_LOG;