厌倦了停机时间并计划调整 MySQL (InnoDB) 中的重做日志文件的大小?在这里我们可以找到笑容!MySQL 8.0.30 的最新版本 (2022-07-26) 添加了 InnoDB 重做日志的在线调整大小功能。
需要重做日志
重做日志在关系数据库中起着至关重要的作用。它主要确保数据库的持久性,它是 ACID 属性中的 D(持久性)。重做日志在崩溃恢复期间重放已提交的事务。
InnoDB 重做日志 8.0.30 之前
在 MySQL 8.0.30 版本之前,重做日志是物理上位于磁盘上的文件,名为ib_logfile0和ib_logfile1。重做日志文件的数量和大小分别由 innodb_log_files_in_group和innodb_log_file_size变量控制。从下图可以更好地理解。
InnoDB 重做日志 8.0.30 之后
拥有正确的重做日志文件大小是 MySQL 顺利运行的基础。但要管理和配置大小,我们需要重新启动 MySQL,这在生产数据库服务器中并不总是一件容易的事情。
这就是最新的 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设置:
代码语言:javascript复制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,则重做日志将位于以下位置
代码语言:javascript复制/data/mysql/#innodb_redo
现在重做日志充当队列,在以前的 MySQL 版本中它是一个循环文件。较旧的重做日志文件现在已被清除。
如上所述,重做日志位于文件夹#innodb_redo中。此文件夹中至少维护 32 个重做日志文件。
代码语言:javascript复制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
重启后重做日志上方。所有后缀为_tmp 的重做日志(即 31 个)都是仍在等待使用的备用重做日志,并且有一个由 InnoDB 使用的活动文件。这里#innodb_redo中有 3.2MB(约),共 32 个重做日志文件,总大小为 100MB 。
重做日志文件名为#ib_redoNNNN(活动文件)和#ib_redoNNNN_tmp(备用重做日志)。重做编号 (NNNN) 递增。
现在如何调整重做日志的大小?
一旦为您的数据库工作负载计算出最佳重做日志大小。重做日志可以轻松调整大小,我已将重做日志大小从默认的 100 MB 修改为 2GB。
代码语言:javascript复制mysql> set persist innodb_redo_log_capacity=2*1024*1024*1024;
Query OK, 0 rows affected (0.01 sec)
代码语言:javascript复制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 的状态(增加或减少)。
代码语言:javascript复制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 错误日志表是在 MySQL 8.0.22 中引入的。这可以帮助更轻松地跟踪 InnoDB 重做调整大小。
代码语言:javascript复制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 的性能模式下的新表来监控重做日志槽及其状态。
代码语言:javascript复制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 中的重做文件
需要考虑的事情
- 确保在配置文件中保留重做日志容量或使用“SET PERSIST”。
- 检查您的物理备份工具的兼容性。
- 停止依赖innodb_log_file_size和innodb_log_files_in_group
此功能可以节省重做日志调整大小的停机时间,并简化动态工作负载的性能调整。随着越来越多的数据库转向 K8 和 DBaaS,此功能是一个福音。随着 MySQL 的发布,Percona 服务器将获得此功能。MariaDB 在 MariaDB 10.5 中对重做日志文件有类似的实现(单个重做文件),但企业 MariaDB 中的重做日志调整大小是动态的。