厌倦了停机并计划在 MySQL (InnoDB) 中调整重做日志文件的大小?在这里,我们可以找到我们脸上的笑容!MySQL 8.0.30 ( 2022-07-26 ) 的最新版本增加了 InnoDB 重做日志的在线调整大小。
概括
- 需要重做日志
- 8.0.30 之前的 InnoDB 重做日志
- 8.0.30 之后的 InnoDB 重做日志
- InnoDB 重做日志中有什么新内容?
- 新的重做日志在哪里?
- 现在如何调整重做日志的大小?
- 如何监控 InnoDB 重做日志调整大小?
- 状态变量
- 错误日志表
- 状态变量
- 新的重做日志在哪里?
- 监控和仪表?
- 比较表?
- 需要考虑的事情
- 结论
需要重做日志
重做日志在关系数据库中起着至关重要的作用。它主要保证数据库的持久性,在ACID属性中是D(durability)。重做日志在崩溃恢复期间重播提交的事务。
8.0.30 之前的 InnoDB 重做日志
在 MySQL 8.0.30 版本之前,重做日志是物理上位于名为ib_logfile0和ib_logfile1的磁盘上的“文件” 。重做日志文件的数量和大小分别由innodb_log_files_in_group和innodb_log_file_size变量控制。从下图中有一个更好的理解。

8.0.30 之后的 InnoDB 重做日志
拥有正确的重做日志文件大小是 MySQL 顺利运行而无需挣扎的基础。但是为了管理和配置大小,我们需要重新启动 MySQL,这在生产数据库服务器中并不总是一件容易的事。
Advertisements
REPORT THIS ADPRIVACY
在这里,最新的 MySQL 版本 8.0.30 中的 InnoDB 支持在运行时更改“ innodb_redo_log_capacity ”系统变量,因此我们可以动态增加或减少重做日志占用的磁盘空间。它不需要重启 MySQL。
还有一些令人兴奋的变量和调整需要了解。
此变量取代了innodb_log_files_in_group和innodb_log_file_size变量。意味着当定义了 innodb_redo_log_capacity 设置时,将忽略innodb_log_files_in_group和innodb_log_file_size设置;要使用此公式计算innodb_redo_log_capacity设置:
innodb_redo_log_capacity = innodb_log_files_in_group * innodb_log_file_size
如果没有设置这些变量,则重做日志容量设置为默认值 104857600 字节 (100MB)。我们可以为这个“innodb_redo_log_capacity”变量设置的最小值是
8 MB,最大值是 128GB。

InnoDB 重做日志中有什么新内容?
在 8.0.30 中,InnoDB 尝试总共维护 32 个重做日志文件,每个文件等于 1/32 * innodb_redo_log_capacity,默认为 100MB。现在我们可以观察到每个大小为 3.2MB 的重做日志。(即;3.2*32= 100 MB)
新的重做日志在哪里?
默认情况下,新的重做日志位于 MySQL 数据目录中的子目录中。如果数据目录在/data/mysql那么重做日志将在下面的位置
/data/mysql/#innodb_redo现在重做日志充当队列,在之前的 MySQL 版本中它是一个循环文件。旧的重做日志文件现在被清除。
如上所述,重做日志位于文件夹#innodb_redo中。该文件夹中至少维护了 32 个重做日志文件。
ls -ltrh
total 100M
-rw-r-----. 1 mysql mysql 3.2M Aug 25 00:14 #ib_redo2484_tmp
-rw-r-----. 1 mysql mysql 3.2M Aug 25 00:14 #ib_redo2485_tmp
-rw-r-----. 1 mysql mysql 3.2M Aug 25 00:14 #ib_redo2486_tmp
-rw-r-----. 1 mysql mysql 3.2M Aug 25 00:14 #ib_redo2487_tmp
-rw-r-----. 1 mysql mysql 3.2M Aug 25 00:14 #ib_redo2488_tmp
-rw-r-----. 1 mysql mysql 3.2M Aug 25 00:14 #ib_redo2489_tmp
-rw-r-----. 1 mysql mysql 3.2M Aug 25 00:14 #ib_redo2490_tmp
-rw-r-----. 1 mysql mysql 3.2M Aug 25 00:14 #ib_redo2491_tmp
-rw-r-----. 1 mysql mysql 3.2M Aug 25 00:14 #ib_redo2492_tmp
-rw-r-----. 1 mysql mysql 3.2M Aug 25 00:14 #ib_redo2493_tmp
-rw-r-----. 1 mysql mysql 3.2M Aug 25 00:14 #ib_redo2494_tmp
-rw-r-----. 1 mysql mysql 3.2M Aug 25 00:14 #ib_redo2495_tmp
-rw-r-----. 1 mysql mysql 3.2M Aug 25 00:14 #ib_redo2496_tmp
-rw-r-----. 1 mysql mysql 3.2M Aug 25 00:14 #ib_redo2497_tmp
-rw-r-----. 1 mysql mysql 3.2M Aug 25 00:14 #ib_redo2498_tmp
-rw-r-----. 1 mysql mysql 3.2M Aug 25 00:14 #ib_redo2499_tmp
-rw-r-----. 1 mysql mysql 3.2M Aug 25 00:14 #ib_redo2500_tmp
-rw-r-----. 1 mysql mysql 3.2M Aug 25 00:14 #ib_redo2501_tmp
-rw-r-----. 1 mysql mysql 3.2M Aug 25 00:14 #ib_redo2502_tmp
-rw-r-----. 1 mysql mysql 3.2M Aug 25 00:14 #ib_redo2503_tmp
-rw-r-----. 1 mysql mysql 3.2M Aug 25 00:14 #ib_redo2504_tmp
-rw-r-----. 1 mysql mysql 3.2M Aug 25 00:14 #ib_redo2505_tmp
-rw-r-----. 1 mysql mysql 3.2M Aug 25 00:14 #ib_redo2506_tmp
-rw-r-----. 1 mysql mysql 3.2M Aug 25 00:14 #ib_redo2507_tmp
-rw-r-----. 1 mysql mysql 3.2M Aug 25 00:14 #ib_redo2508_tmp
-rw-r-----. 1 mysql mysql 3.2M Aug 25 00:14 #ib_redo2509_tmp
-rw-r-----. 1 mysql mysql 3.2M Aug 25 00:14 #ib_redo2510_tmp
-rw-r-----. 1 mysql mysql 3.2M Aug 25 00:14 #ib_redo2511_tmp
-rw-r-----. 1 mysql mysql 3.2M Aug 25 00:14 #ib_redo2512_tmp
-rw-r-----. 1 mysql mysql 3.2M Aug 25 00:14 #ib_redo2513_tmp
-rw-r-----. 1 mysql mysql 3.2M Aug 25 00:14 #ib_redo2514_tmp
-rw-r-----. 1 mysql mysql 3.2M Aug 25 00:14 #ib_redo2483上面的redo log是重启后。所有后缀“_tmp”即;31 个是仍在等待使用的备用重做日志,并且 InnoDB 使用了一个活动文件。这里有 32 个重做日志文件中的 3.2MB(大约),总大小为 100MB,位于#innodb_redo中。
重做日志文件被命名为#ib_redoNNNN用于活动文件和#ib_redoNNNN_tmp用于备用重做日志。重做编号 (NNNN) 递增。
现在如何调整重做日志的大小?
一旦为您的数据库工作负载计算了最佳重做日志大小。重做日志可以轻松调整大小,我已将重做日志大小从默认的 100 MB 修改为 2GB。
mysql> set persist innodb_redo_log_capacity=2*1024*1024*1024;
Query OK, 0 rows affected (0.01 sec) ls -ltrh
total 2.0G
-rw-r-----. 1 mysql mysql 3.2M Aug 25 00:14 #ib_redo2483
-rw-r-----. 1 mysql mysql 64M Aug 25 00:16 #ib_redo2484_tmp
-rw-r-----. 1 mysql mysql 64M Aug 25 00:16 #ib_redo2485_tmp
-rw-r-----. 1 mysql mysql 64M Aug 25 00:16 #ib_redo2486_tmp
-rw-r-----. 1 mysql mysql 64M Aug 25 00:16 #ib_redo2487_tmp
-rw-r-----. 1 mysql mysql 64M Aug 25 00:16 #ib_redo2488_tmp
-rw-r-----. 1 mysql mysql 64M Aug 25 00:16 #ib_redo2489_tmp
-rw-r-----. 1 mysql mysql 64M Aug 25 00:16 #ib_redo2490_tmp
-rw-r-----. 1 mysql mysql 64M Aug 25 00:16 #ib_redo2491_tmp
-rw-r-----. 1 mysql mysql 64M Aug 25 00:16 #ib_redo2492_tmp
-rw-r-----. 1 mysql mysql 64M Aug 25 00:16 #ib_redo2493_tmp
-rw-r-----. 1 mysql mysql 64M Aug 25 00:16 #ib_redo2494_tmp
-rw-r-----. 1 mysql mysql 64M Aug 25 00:16 #ib_redo2495_tmp
-rw-r-----. 1 mysql mysql 64M Aug 25 00:16 #ib_redo2496_tmp
-rw-r-----. 1 mysql mysql 64M Aug 25 00:16 #ib_redo2497_tmp
-rw-r-----. 1 mysql mysql 64M Aug 25 00:16 #ib_redo2498_tmp
-rw-r-----. 1 mysql mysql 64M Aug 25 00:16 #ib_redo2499_tmp
-rw-r-----. 1 mysql mysql 64M Aug 25 00:16 #ib_redo2500_tmp
-rw-r-----. 1 mysql mysql 64M Aug 25 00:16 #ib_redo2501_tmp
-rw-r-----. 1 mysql mysql 64M Aug 25 00:16 #ib_redo2502_tmp
-rw-r-----. 1 mysql mysql 64M Aug 25 00:16 #ib_redo2503_tmp
-rw-r-----. 1 mysql mysql 64M Aug 25 00:16 #ib_redo2504_tmp
-rw-r-----. 1 mysql mysql 64M Aug 25 00:16 #ib_redo2505_tmp
-rw-r-----. 1 mysql mysql 64M Aug 25 00:16 #ib_redo2506_tmp
-rw-r-----. 1 mysql mysql 64M Aug 25 00:16 #ib_redo2507_tmp
-rw-r-----. 1 mysql mysql 64M Aug 25 00:16 #ib_redo2508_tmp
-rw-r-----. 1 mysql mysql 64M Aug 25 00:16 #ib_redo2509_tmp
-rw-r-----. 1 mysql mysql 64M Aug 25 00:16 #ib_redo2510_tmp
-rw-r-----. 1 mysql mysql 64M Aug 25 00:16 #ib_redo2511_tmp
-rw-r-----. 1 mysql mysql 64M Aug 25 00:16 #ib_redo2512_tmp
-rw-r-----. 1 mysql mysql 64M Aug 25 00:16 #ib_redo2513_tmp
-rw-r-----. 1 mysql mysql 64M Aug 25 00:16 #ib_redo2514_tmp现在,除了活动文件之外的所有重做文件都被调整为每个文件 64MB(总共 2GB)。
如何监控 InnoDB 重做日志调整大小?
状态变量
MySQL 8.0.30 引入了一个新的状态变量名称Innodb_redo_log_resize_status。可以监控检查 InnoDD redo resize ( upsize 或 downsize ) 的状态。
show global status like 'Innodb_redo_log_resize_status';
+-------------------------------+-------+
| Variable_name | Value |
+-------------------------------+-------+
| Innodb_redo_log_resize_status | OK |
+-------------------------------+-------+
1 row in set (0.00 sec)错误日志表
MySQL 8.0.22 中引入了MySQL 错误日志表。这有助于更轻松地跟踪 InnoDB 重做调整大小。
select (LOGGED),ERROR_CODE,SUBSYSTEM,DATA from performance_schema.error_log where subsystem='INNODB' and DATA like '%redo%' order by LOGGED desc limit 3;
+----------------------------+------------+-----------+----------------------------------------------------------------------------------------------------------------+
| LOGGED | ERROR_CODE | SUBSYSTEM | DATA |
+----------------------------+------------+-----------+----------------------------------------------------------------------------------------------------------------+ |
| 2022-08-25 00:55:53.601520 | MY-013884 | InnoDB | User has set innodb_redo_log_capacity to 2048M. |
| 2022-08-25 00:55:53.601601 | MY-013885 | InnoDB | Redo log has been requested to resize from 100M to 2048M. |
| 2022-08-25 00:55:53.601628 | MY-013887 | InnoDB | Redo log has been resized to 2048M. | |
+----------------------------+------------+-----------+----------------------------------------------------------------------------------------------------------------+监控和仪表?
可以从名为“ innodb_redo_log_files ”的性能模式下的新表中监视重做日志槽及其状态。
select FILE_ID as "Slot_number", (END_LSN-START_LSN) as "Total LSN" , sys.format_bytes(SIZE_IN_BYTES) as SLOT Size, if(IS_FULL="0","Active","In Active") as "Slot Status" from performance_schema.innodb_redo_log_files;
+-------------+----------+-----------+-------------+
| Slot_number | Total LSN | SLOT Size | Slot Status|
+-------------+----------+-----------+-------------+
| 2494 | 67106816 | 64.00 MiB | In Active |
| 2495 | 67106816 | 64.00 MiB | In Active |
| 2496 | 67106816 | 64.00 MiB | In Active |
| 2497 | 67106816 | 64.00 MiB | In Active |
| 2498 | 67106816 | 64.00 MiB | In Active |
| 2499 | 67106816 | 64.00 MiB | In Active |
| 2500 | 67106816 | 64.00 MiB | In Active |
| 2501 | 67106816 | 64.00 MiB | In Active |
| 2502 | 67106816 | 64.00 MiB | In Active |
| 2503 | 67106816 | 64.00 MiB | In Active |
| 2504 | 67106816 | 64.00 MiB | In Active |
| 2505 | 67106816 | 64.00 MiB | In Active |
| 2506 | 67106816 | 64.00 MiB | In Active |
| 2507 | 67106816 | 64.00 MiB | Active |
+-------------+----------+-----------+-------------+
14 rows in set (0.00 sec)比较表?
让我们比较一下 8.0.30 之前和 8.0.30 之前的重做文件
| 8.0.30 之前 | 在 8.0.30 | |
| 重做日志文件 | 默认有 2 个重做文件 | 默认32个重做日志文件 |
| 重做调整大小 | 静态需要重启 | 动态(不重启) |
| 重做日志写入 | 循环写入(file0->file1->file0) | 日志写入在顺序队列中 |
| 重做日志命名 | 静态命名(ib_logfile0 和 iblogfile1) | 动态命名和递增 (#ib_redoNNNN) |
需要考虑的事情
- 确保在配置文件中保留重做日志容量或使用“SET PERSIST”。
- 检查物理备份工具的兼容性。
- 停止依赖innodb_log_file_size和 innodb_log_files_in_group
结论
此功能可以节省重做日志调整大小的停机时间,并简化动态工作负载的性能调整。随着越来越多的数据库转向 K8 和 DBaaS,这个特性是一个福音。由于 MySQL 已经发布,Percona 服务器将获得此功能。MariaDB 在 MariaDB 10.5 中具有类似的重做日志文件实现(单个重做文件),但重做日志调整大小在企业 MariaDB 中是动态的。
原文标题:Dynamic InnoDB Redo log Resize MySQL 8.0.30
原文作者: mahaganapathineedi
原文链接:https://mydbops.wordpress.com/2022/09/02/online-innodb-redo-log-resize-mysql-8-0/




