一 前言
MySQL redo log记录数据记录变更,以及未数据一致性恢复提供保障。在运维MySQL 过程中,很多DBA 会遇到调整redo log 和redo buffer size 大小的需求,然而修改redo log 文件大小需要重启,用户体验不好。不过 MySQL 8.0.30 版本中提供动态调整redo log 文件大小的功能。
本文将介绍MySQL 8.0.30 版本中redo log 有哪些改变。
二 redo log
2.1 参数控制
从 MySQL 8.0.30 开始, innodb_redo_log_capacity
系统变量控制 redo log 总的大小。
注意:
因为在该版本以及之后的版本参数
innodb_log_file_size
和innodb_log_files_in_group
已经被废弃并且参数innodb_redo_log_capacity
变量取代 。
当 设置 参数 innodb_redo_log_capacity
时 ,系统会忽略 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
,即100MB,最大重做日志容量为 128GB。
我们可以在 实例启动 时或 实例运行过程中使用 SET GLOBAL 语句修改redo log 容量。详情请参考 2.3 小结。
2.2 redo 日志位置
redo log 文件存放的位置由参数 innodb_log_group_home_dir
控制,如果没有指定具体目录,系统默认会将redo log存储到 data 目录的#innodb_redo
目录。
master [localhost:22031]> show variables like 'innodb_log_group_home_dir';
+---------------------------+-------+
| Variable_name | Value |
+---------------------------+-------+
| innodb_log_group_home_dir | ./ |
+---------------------------+-------+
1 row in set (0.00 sec)
需要注意的是,如果设置 innodb_log_group_home_dir =
会启动失败。遇到如下报错:
/u02/sandboxes/mysql_home/rsandbox_8_0_30/master/data/redo_log
2022-08-14T09:32:11.350596Z 1 [ERROR] [MY-013862] [InnoDB] Neither found #innodb_redo subdirectory, nor ib_logfile* files in /u02/sandboxes/mysql_home/rsandbox_8_0_30/master/data/redo_log/
更改redo 文件的位置,innodb_log_group_home_dir
指定的文件夹下必须创建 #innodb_redo
目录。
innodb_log_group_home_dir
=/u02/sandboxes/mysql_home/rsandbox_8_0_30/master/data/redo_log/#innodb_redo
master [localhost:22031] {msandbox} ((none)) > show variables like 'innodb_log_group_home_dir';
+---------------------------+-----------------------------------------------------------------+
| Variable_name | Value |
+---------------------------+-----------------------------------------------------------------+
| innodb_log_group_home_dir | /u02/sandboxes/mysql_home/rsandbox_8_0_30/master/data/redo_log/ |
+---------------------------+-----------------------------------------------------------------+
在 MySQL 8.0.30 版本中,MySQL会生成32个 redo log 文件,每个文件的大小等于 1/32 * innodb_redo_log_capacity
;修改redo log容量大小后每个文件大小可能会有所不同 。
redo log 有两种:正在使用的和未被使用的,分别使用 #ib_redoNN
和 #ib_redoNN_tmp
其中NN是重做日志文件编号。
以下示例显示了一个 目录中的重做日志文件,其中有 31 个活动重做日志文件和 1 个备用重做日志文件,按顺序编号:
#ib_redo0 #ib_redo12_tmp #ib_redo15_tmp #ib_redo18_tmp
#ib_redo20_tmp #ib_redo23_tmp #ib_redo26_tmp #ib_redo29_tmp
#ib_redo31_tmp #ib_redo5_tmp #ib_redo8_tmp #ib_redo10_tmp
#ib_redo13_tmp #ib_redo16_tmp #ib_redo19_tmp #ib_redo21_tmp
#ib_redo24_tmp #ib_redo27_tmp #ib_redo2_tmp #ib_redo3_tmp
#ib_redo6_tmp #ib_redo9_tmp #ib_redo11_tmp #ib_redo14_tmp
#ib_redo17_tmp #ib_redo1_tmp #ib_redo22_tmp #ib_redo25_tmp
#ib_redo28_tmp #ib_redo30_tmp #ib_redo4_tmp #ib_redo7_tmp
2.3 测试动态修改 redo size
提前创建表
CREATE TABLE `sbtest1` (
`id` int NOT AUTO_INCREMENT,
`k` int NOT DEFAULT '0',
`c` char(120) NOT DEFAULT '',
`pad` char(60) NOT DEFAULT '',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=100001 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
1 row in set (0.00 sec)
使用 mysqlslap 对数据库进行压测 5个并发插入数据100w行记录。
/u02/sandboxes/mysql_binary/8.0.30/bin/mysqlslap -umsandbox -pmsandbox -h127.0.0.1 -P22031 --create-schema=test --query "insert into test.sbtest1(k,c,pad) values(floor(rand() *100000)%2048,'a','ddafdfdssssdda');" --number-of-queries=1000000 -c 5
同时动态修改 redo log size, 从整体500MB 调整为1000MB,耗时0.61s
master [localhost:22031]> show variables like 'innodb_redo_log_capacity';
+--------------------------+-----------+
| Variable_name | Value |
+--------------------------+-----------+
| innodb_redo_log_capacity | 524288000 |
+--------------------------+-----------+
1 row in set (0.00 sec)
master [localhost:22031]> set global innodb_redo_log_capacity=1000*1024*1024;
Query OK, 0 rows affected (0.61 sec)
master [localhost:22031] > show variables like 'innodb_redo_log_capacity';
+--------------------------+------------+
| Variable_name | Value |
+--------------------------+------------+
| innodb_redo_log_capacity | 1048576000 |
+--------------------------+------------+
1 row in set (0.00 sec)
修改之后可以通过参数
以查看调整大小操作的状态:
Innodb_redo_log_resize_status
master [localhost:22031] > SHOW STATUS LIKE 'Innodb_redo_log_resize_status';
+-------------------------------+-------+
| Variable_name | Value |
+-------------------------------+-------+
| Innodb_redo_log_resize_status | OK |
+-------------------------------+-------+
1 row in set (0.00 sec)
状态变量显示当前
重做日志容量限制:
Innodb_redo_log_capacity_resized
master [localhost:22031] >SHOW STATUS LIKE 'Innodb_redo_log_capacity_resized';
+----------------------------------+-----------+
| Variable_name | Value |
+----------------------------------+-----------+
| Innodb_redo_log_capacity_resized | 104857600 |
+----------------------------------+-----------+
其他适用的状态变量包括:
Innodb_redo_log_checkpoint_lsn
Innodb_redo_log_current_lsn
Innodb_redo_log_flushed_to_disk_lsn
Innodb_redo_log_logical_size
Innodb_redo_log_physical_size
Innodb_redo_log_read_only
Innodb_redo_log_uuid
我们还可以通过查询
来查看有关活动重做日志文件的信息。以下查询的所有列中检索数据:
performance_schema.innodb_redo_log_files
SELECT FILE_ID, START_LSN, END_LSN, SIZE_IN_BYTES, IS_FULL, CONSUMER_LEVEL
FROM performance_schema.innodb_redo_log_files;
三 小结
MySQL 8.0 我们运维工作带来越来越多的新特性,满足在线,实时的要求,避免数据库切换重启,提升业务系统的稳定性和运维的幸福感。对该功能该兴趣的朋友可以动手测试一下。