14.8.3.5 配置缓冲池刷新

InnoDB在后台执行某些任务,包括从缓冲池中清除脏页。脏页是指已被修改但尚未写入磁盘上数据文件的页。

在 MySQL 5.7 中,缓冲池刷新是由页面清理程序线程执行的。页面清理器线程的数量由innodb_page_cleaners变量控制,该变量的默认值为 4.但是,如果页面清理器线程的数量超过缓冲池实例的数量,则innodb_page_cleaners会自动设置为与innodb_buffer_pool_instances相同的值。

当脏页的百分比达到innodb_max_dirty_pages_pct_lwm变量定义的低水位标记值时,将启动缓冲池刷新。默认的低水位标记为 0,这会禁用此早期冲洗行为。

innodb_max_dirty_pages_pct_lwm阈值的目的是控制缓冲池中脏页的百分比,并防止脏页数量达到innodb_max_dirty_pages_pct变量(默认值为 75)所定义的阈值。InnoDB积极刷新缓冲池页如果缓冲池中的脏页百分比达到innodb_max_dirty_pages_pct阈值。

其他变量允许对缓冲池刷新行为进行微调:

  • innodb_flush_neighbors变量定义从缓冲池刷新页面是否也以相同程度刷新其他脏页面。

  • 设置为 0 将禁用innodb_flush_neighbors。同样程度的脏页不会被刷新。

    • 默认设置 1 会以相同程度刷新连续的脏页。

    • 设置为 2 会以相同程度刷新脏页。

当 table 数据存储在传统的HDD存储设备上时,与在不同时间刷新单个页面相比,在一次操作中刷新相邻页面减少了 I/O 开销(主要用于磁盘查找操作)。对于存储在SSD上的 table 数据,查找时间不是重要因素,您可以禁用此设置以分散写操作。

  • innodb_lru_scan_depth变量针对每个缓冲池实例指定页面清洁器线程扫描以查找要刷新的脏页面的缓冲池 LRU 列 table 的下行距离。这是页面清洁器线程每秒执行一次的后台操作。

小于默认值的设置通常适用于大多数工作负载。明显高于必要值的值可能会影响性能。仅在典型工作负载下具有备用 I/O 容量时,才考虑增加该值。相反,如果写密集型工作负载使 I/O 容量饱和,请减小该值,尤其是在大型缓冲池的情况下。

调整innodb_lru_scan_depth时,请从较低的值开始,然后向上配置该设置,以极少看到零可用页面为目标。另外,在更改缓冲池实例的数量时,请考虑调整innodb_lru_scan_depth,因为innodb_lru_scan_depth * innodb_buffer_pool_instances定义了每秒页面清洁器线程执行的工作量。

innodb_flush_neighborsinnodb_lru_scan_depth变量主要用于写密集型工作负载。在繁琐的 DML 活动中,如果刷新不够积极,刷新可能会落在后面;如果刷新过于激进,则磁盘写入可能会使 I/O 容量饱和。理想的设置取决于您的工作量,数据访问模式和存储配置(例如,数据是存储在 HDD 还是 SSD 设备上)。

Adaptive Flushing

InnoDB使用自适应刷新算法,根据重做日志生成的速度和当前刷新率动态调整刷新率。目的是通过确保刷新活动与当前工作负载保持同步来使总体性能平稳。自动调整刷新速率有助于避免由于缓冲池刷新而导致的 I/O 活动突发影响普通读取和写入活动可用的 I/O 容量时发生的吞吐量突然下降。

例如,尖锐的检查点通常与写密集型工作负载相关联,这些工作负载会生成大量的重做条目,这些尖锐的检查点可能会导致吞吐量的突然变化。当InnoDB要重用日志文件的一部分时,将出现一个尖锐的检查点。在执行此操作之前,必须清除日志文件该部分中所有具有重做条目的脏页。如果日志文件已满,则会出现尖锐的检查点,从而导致吞吐量暂时降低。即使未达到innodb_max_dirty_pages_pct阈值,也会发生这种情况。

自适应刷新算法通过跟踪缓冲池中的脏页数和生成重做日志记录的速率来帮助避免此类情况。根据此信息,它决定每秒从缓冲池刷新多少脏页,从而允许它 Management 工作负载的突然变化。

innodb_adaptive_flushing_lwm变量定义重做日志容量的低水位线。超过该阈值时,即使禁用了innodb_adaptive_flushing变量,也会启用自适应刷新。

内部基准测试 table 明,该算法不仅可以长期保持吞吐量,而且还可以显着提高整体吞吐量。但是,自适应刷新会显着影响工作负载的 I/O 模式,可能并不适合所有情况。当重做日志有填满的危险时,它将提供最大的好处。如果自适应刷新不适合您的工作负载 Feature,则可以禁用它。由innodb_adaptive_flushing变量控制的自适应刷新,默认情况下已启用。

innodb_flushing_avg_loops定义InnoDB保留先前计算的刷新状态快照的迭代次数,控制自适应刷新对前台工作负载变化的响应速度。较高的innodb_flushing_avg_loops值 table 示InnoDB可使先前计算的快照保持更长的时间,因此自适应刷新的响应速度更慢。设置高值时,重要的是确保重做日志利用率不达到 75%(异步刷新开始的硬编码限制),并且innodb_max_dirty_pages_pct阈值将脏页数保持在适合工作负荷的水平。

具有一致的工作负载,较大的日志文件大小(innodb_log_file_size)和未达到日志空间利用率 75%的小峰值的系统应使用较高的innodb_flushing_avg_loops值,以保持刷新尽可能顺利。对于负载高峰或日志文件不能提供大量空间的系统,较小的值允许刷新以紧密跟踪工作负载变化,并有助于避免达到 75%的日志空间利用率。

请注意,如果刷新落后,则缓冲池刷新的速率可能会超过InnoDB可用的 I/O 容量(如innodb_io_capacity设置所定义)。 innodb_io_capacity_max值定义了这种情况下 I/O 容量的上限,因此 I/O 活动的高峰不会消耗服务器的整个 I/O 容量。

innodb_io_capacity设置适用于所有缓冲池实例。刷新脏页后,I/O 容量将在缓冲池实例之间平均分配。