8.5.4-优化InnoDB的redo日志

在优化redo日志时,考虑以下原则:

  • 增加redo日志文件的大小。当InnoDB将redo日志文件写满时,它必须在checkpoint中将buffer pool中修改过的内容写到磁盘上(刷脏)。redo日志文件过小会导致很多必要的写磁盘。

从MySQL8.0.30开始,redo日志文件大小由设置 innodb_redo_log_capacity决定。InnoDB最多维护32个大小一样的redo日志文件,每个文件的带下是1/32 * innodb_redo_log_capacity。因此,修改innodb_redo_log_capacity设置就会改变redo日志文件大小。

在MySQL8.0.30之前,通过innodb_log_file_size和 innodb_log_files_in_group变量设置innodb日志文件大小。

想了解更多关于redo日志文件的信息,请查阅章节 15.6.5,“Redo Log”

  • 考虑增加log buffer的大小。一个大的log buffer让大事务不必再commit之前将日志写入到磁盘。因此,如果你在事务中update,insert,或delete大量记录,调大log buffer大小会节省磁盘I/O。在MySQL8.0中,可以通脱设置项 innodb_log_buffer_size来对Log buffer大小进行动态设置。

  • 设置配置项innodb_log_write_ahead_size来避免"read-on-write"。这个选项定义了redo日志写前块的大小。将innodb_log_write_ahead_size设置成与操作系统或文件系统缓冲块大小匹配的值。当redo日志没有被全部缓存到操作系统或文件系统中时,会发生ROW。未完全缓存的原因是redo日志读前块大小和操作系统或文件系统缓存块大小不匹配。

innodb_log_write_ahead_size的有效值是InnoDB日志块大小的倍数(2^n)。其最小值是InnoDB日志文件块大小(512)。当指明最小值时,Write-ahead不会发生。其最大值时innodb_page_size的值。如果你设置的innodb_log_write_ahead_size值比如innodb_page_size值大,innodb_log_write_ahead_size会被设置成innodb_page_size的值。

如果innodb_log_write_ahead_size的值比操作系统或文件系统缓存块大小相比太小,会导致read-on-write。值过大则可能会因为在写日志文件时同时写入多个块,对fsync性能有一些影响。

  • MySQL8.0.11引入了专门的日志写入线程,用于将log buffer中的redo日志记录写入系统缓冲区,并将系统缓冲区中的内容写入edo日志文件。之前,有独立的用户线程来处理这些任务。从MySQL8.0.22开始,你可以通过变量innodb_log_writer_threads变量来启用或禁用日志写入线程。在高并发系统中,专门的日志写入线程可以提高性能。单对于低并发系统来说,禁用日志写入线程,性能可能会更好一点。

  • 优化等待刷新redo日志的用户线程对自旋延迟的使用。自旋延迟有助于减少延迟。在并发量小的时候,减少延迟的优先级可能不高,而且在并发量小时减少自旋延迟可能会减少能源消耗。在并发量高的时候,你可能不想在自旋等待上花费太多能源,这些能源原本可以用在其它工作任务上。下面的变量可以用来设置使用自旋延迟时的高水位和低水位边界值:

    • innodb_log_wait_for_flush_spin_hwm:定义最大平均日志刷新时间,超过这个值后,用户线程在等待刷新redo日志时不再自旋等待。默认值是400微妙。
    • innodb_log_spin_cpu_abs_lwm:定义了cpu使用率的最小值,低于该值时,用户线程在等待刷新redo日志时不再自旋等待。该值各个cpu内核使用率之和。例如,默认值是80%,是一个cpu内核的80%。在多核cpu上,值为150表明一个cpu使用率是100%的内核,再加上一个使用率是50%的内核。
    • innodb_log_spin_cpu_pct_hwm:定义了cpu使用率的最大值,高于该值时,用户线程在等待刷新redo日志时不再自旋等待。改制是所有核心处理能力之和的百分比。双核,使用率100%,是四核心cpu处理能力的50%。 innodb_log_spin_cpu_pct_hwm配置考虑到了cpu亲和性。例如,如果服务有48个核心,但是mysqld只固定在4个核心上,那其它44个核心会被忽略。