本文是MySQL 8.0 Dynamic Redo Log Sizing[1]这篇文章的翻译。如有翻译不当的地方,敬请谅解,请尊重原创和翻译劳动成果,转载的时候请注明出处。谢谢! 这篇博文将讨论MySQL 8.0.30中引入的最新功能/特性:重做日志动态调整大小(dynamic redo log sizing)。除了InnoDB 缓冲池(buffer pool)大小之外,我们可以说合适的重做日志大小对于MySQL性能至关重要。有许多关于如何计算合适的重做日志大小的博客文章。其中最经典的博客文章之一来自 Baron:How to calculate a good InnoDB log file size[2](这篇博客文章是2008年发布的,但文中计算redo log大小的公式仍然是一个有效的公式) 现在,这个功能/特性试图解决哪个问题呢? 在MySQL中,缓冲池(buffer pool)和重做日志大小是不经常更改的参数设置。通常,这些参数是在数据库安装期间设置的;之后,它们就会被遗忘,直到一些问题出现为止。问题是过去它们是静态的,这意味着您必须重新启动MySQL才能使参数变更生效。 MySQL在MySQL 5.7中通过动态调整缓冲池(buffer bool)大小解决了缓冲池问题。现在,MySQL 8.0.30解决了重做日志的这个问题。调整重做日志大小非常简单明了: 此参数设置可将重做日志大小调整为比当前定义的值更大或更小的值。为了实现此目的,重做日志文件现在驻留在datadir指定的新目录中#innodb_redo中,除非你通过变量innodb_log_group_home_dir指定了不同的目录。这个目录下的重做日志文件有两种类型:普通重做日志文件和备用重做日志文件。普通重做日志文件是正在使用的重做日志文件。备用重做日志文件是那些等待使用的重做日志文件。InnoDB总共维护了32个重做日志文件,每个文件大小等于1/32 * innodb_redo_log_capacity;但是,修改innodb_redo_log_capacity参数后,重做日志文件大小可能会暂时有所不同。 重做日志文件使用#ib_redoN命名约定,其中N是重做日志文件编号。备用重做日志文件由后缀表示_tmp。以下示例显示#innodb_redo 目录中的重做日志文件,其中 18 个活动重做日志文件和 14 个备用重做日志文件按顺序编号。 MySQL提供了几个状态变量用于监视重做日志和重做日志容量调整操作;例如,您可以通过查询Innodb_redo_log_resize_status以查看调整大小操作的状态: 状态变量Innodb_redo_log_capacity_resized显示当前重做日志的容量限制: 其他状态变量包括: MySQL 8.0.30 还引入了一些与此问题相关的新错误消息。其中一些包括: 如果您想查看更多信息,可以使用此链接[3]。所有与重做日志错误相关的消息都使用ER_IB_MSG_LOG_WRITER_ 命名约定。 有了这些新的状态变量,我们可以使用以下查询来估计重做日志大小: 根据上一个查询提供的输出,我们运行以下命令: 因此,在这种情况下,在重做日志文件中写入大约为250MB/分钟,那么一小时恰好是 250*60(1 小时),相当于 15GB。 为了实现这个新功能,MySQL 弃用了两个参数:innodb_log_files_in_group和innodb_log_file_size 。 如果您尝试在文件中设置它们my.cnf,它们将被忽略,并且错误日志中将打印警告: 重做日志动态调整大小为 DBA 提供了更大的灵活性,以防万一需要调整重做日志大小,应用程序不能因MySQL重新启动而停止对外服务的情况。截至撰写本文时,还没有与此功能相关的错误报告。建议之一是检查您的备份工具是否与 MySQL 8.0.30 及其新功能兼容。最后,由于一些参数已经弃用,请务必检查现有的my.cnf配置文件。 1: https://www.percona.com/blog/mysql-8-0-dynamic-redo-log-sizing/ 2: https://www.percona.com/blog/2008/11/21/how-to-calculate-a-good-innodb-log-file-size/ 3: https://github.com/mysql/mysql-server/blob/8.0/share/messages_to_error_log.txtmysql> SET GLOBAL innodb_redo_log_capacity = 2*1024*1024*1024;
$ ls
#ib_redo31 #ib_redo33 #ib_redo35 #ib_redo37 #ib_redo39 #ib_redo41 #ib_redo43 #ib_redo45 #ib_redo47 #ib_redo49_tmp #ib_redo51_tmp #ib_redo53_tmp #ib_redo55_tmp #ib_redo57_tmp #ib_redo59_tmp #ib_redo61_tmp
#ib_redo32 #ib_redo34 #ib_redo36 #ib_redo38 #ib_redo40 #ib_redo42 #ib_redo44 #ib_redo46 #ib_redo48 #ib_redo50_tmp #ib_redo52_tmp #ib_redo54_tmp #ib_redo56_tmp #ib_redo58_tmp #ib_redo60_tmp #ib_redo62_tmpmysql> SHOW GLOBAL STATUS LIKE 'Innodb_redo_log_resize_status';
+-------------------------------+-------+
| Variable_name | Value |
+-------------------------------+-------+
| Innodb_redo_log_resize_status | OK |
+-------------------------------+-------+mysql> SHOW GLOBAL STATUS LIKE 'Innodb_redo_log_capacity_resized';
+----------------------------------+------------+
| Variable_name | Value |
+----------------------------------+------------+
| Innodb_redo_log_capacity_resized | 3221225472 |
+----------------------------------+------------+Innodb_redo_log_checkpoint_lsn
Innodb_redo_log_current_lsn
Innodb_redo_log_flushed_to_disk_lsn
Innodb_redo_log_logic_size
Innodb_redo_log_physical_size
Innodb_redo_log_read_only
Innodb_redo_log_uuidER_IB_MSG_LOG_WRITER_OUT_OF_SPACE
ER_IB_MSG_LOG_WRITER_ABORTS_LOG_ARCHIVER
ER_IB_MSG_LOG_WRITER_WAITING_FOR_ARCHIVER
ER_IB_MSG_LOG_WRITER_WAIT_ON_NEW_LOG_FILE
ER_IB_MSG_LOG_WRITER_ENTERED_EXTRA_MARGIN
ER_IB_MSG_LOG_WRITER_WAIT_ON_CONSUMER估计重做日志容量
mysql> SHOW GLOBAL STATUS LIKE 'Innodb_redo_log_current_lsn'; SELECT SLEEP(60); SHOW GLOBAL STATUS LIKE 'Innodb_redo_log_current_lsn';
mysql > SELECT ABS(20641693317 - 20903377487) / 1024 / 1024 AS MB_per_min;
+--------------+
| MB_per_min |
+--------------+
| 249.56147194 |
+--------------+
1 row in set (0.00 sec)已弃用的参数
2022-08-07T20:23:39.898370Z 0 [Warning] [MY-013869] [InnoDB] Ignored deprecated configuration parameter innodb_log_file_size. Used innodb_redo_log_capacity instead.
2022-08-07T20:23:39.898441Z 0 [Warning] [MY-013870] [InnoDB] Ignored deprecated configuration parameter innodb_log_files_in_group. Used innodb_redo_log_capacity instead.结论
参考资料