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_max_dirty_pages_pct_lwm
,该值应始终低于该
innodb_max_dirty_pages_pct
值。
附加变量允许微调缓冲池刷新行为:
该
innodb_flush_neighbors
变量定义从缓冲池中刷新页面是否也刷新相同范围内的其他脏页。设置为 0 将禁用
innodb_flush_neighbors
。相同范围内的脏页不会被刷新。默认设置 1 会刷新同一范围内的连续脏页。
设置为 2 会刷新相同范围内的脏页。
当表数据存储在传统 HDD存储设备上时,与在不同时间刷新单个页面相比,在一次操作中刷新相邻页面可减少 I/O 开销(主要用于磁盘查找操作)。对于存储在SSD上的表数据,寻道时间不是一个重要因素,您可以禁用此设置以分散写入操作。
对于每个缓冲池实例,该
innodb_lru_scan_depth
变量指定页面清理器线程扫描缓冲池 LRU 列表中的多远以查找要刷新的脏页。这是页面清理器线程每秒执行一次的后台操作。小于默认值的设置通常适用于大多数工作负载。明显高于必要值的值可能会影响性能。只有在典型工作负载下有备用 I/O 容量时,才考虑增加该值。相反,如果写入密集型工作负载使您的 I/O 容量饱和,请降低该值,尤其是在大型缓冲池的情况下。
调整时
innodb_lru_scan_depth
,从低值开始并向上配置设置,目标是很少看到零空闲页面。此外,innodb_lru_scan_depth
在更改缓冲池实例数时考虑进行调整,因为innodb_lru_scan_depth
*innodb_buffer_pool_instances
定义了页面清理器线程每秒执行的工作量。
和变量主要用于写入密集型工作负载innodb_flush_neighbors
。
innodb_lru_scan_depth
对于繁重的 DML 活动,如果不够激进,刷新可能会落后,或者如果刷新过于激进,磁盘写入会使 I/O 容量饱和。理想的设置取决于您的工作负载、数据访问模式和存储配置(例如,数据是存储在 HDD 还是 SSD 设备上)。
InnoDB
使用自适应刷新算法根据重做日志生成速度和当前刷新率动态调整刷新率。目的是通过确保刷新活动与当前工作负载保持同步来平滑整体性能。自动调整刷新率有助于避免吞吐量突然下降,这种情况可能会在缓冲池刷新导致的 I/O 活动突发影响普通读写活动可用的 I/O 容量时发生。
例如,尖锐的检查点通常与生成大量重做条目的写入密集型工作负载相关联,可能会导致吞吐量突然变化。当InnoDB
想要重用日志文件的一部分时,会出现尖锐的检查点。在这样做之前,必须刷新日志文件该部分中具有重做条目的所有脏页。如果日志文件已满,则会出现尖锐的检查点,导致吞吐量暂时下降。即使
innodb_max_dirty_pages_pct
未达到阈值,也会发生这种情况。
自适应刷新算法通过跟踪缓冲池中脏页的数量和生成重做日志记录的速率来帮助避免此类情况。根据此信息,它决定每秒从缓冲池中刷新多少脏页,这使其能够管理工作负载的突然变化。
该
innodb_adaptive_flushing_lwm
变量定义重做日志容量的低水位线。当超过该阈值时,将启用自适应刷新,即使
innodb_adaptive_flushing
禁用该变量也是如此。
内部基准测试表明,该算法不仅可以随着时间的推移保持吞吐量,还可以显着提高整体吞吐量。但是,自适应刷新会显着影响工作负载的 I/O 模式,并且可能并不适用于所有情况。当重做日志有填满的危险时,它会提供最大的好处。如果自适应刷新不适合您的工作负载特性,您可以禁用它。由
innodb_adaptive_flushing
变量控制的自适应刷新,默认启用。
innodb_flushing_avg_loops
定义
InnoDB
保留先前计算的刷新状态快照的迭代次数,控制自适应刷新响应前台工作负载变化的速度。高
innodb_flushing_avg_loops
值意味着InnoDB
将先前计算的快照保持更长时间,因此自适应刷新响应更慢。当设置一个高值时,重要的是要确保重做日志利用率不达到 75%(异步刷新开始的硬编码限制),并且该
innodb_max_dirty_pages_pct
阈值将脏页的数量保持在适合工作负载的水平。
具有一致工作负载、较大日志文件大小 ( innodb_log_file_size
) 和未达到 75% 日志空间利用率的小峰值的系统应使用高
innodb_flushing_avg_loops
值以保持刷新尽可能顺利。对于具有极端负载峰值或未提供大量空间的日志文件的系统,较小的值允许刷新以密切跟踪工作负载变化,并有助于避免达到 75% 的日志空间利用率。
请注意,如果刷新落后,缓冲池刷新的速率可能会超过 可用的 I/O 容量
InnoDB
,如设置所定义
innodb_io_capacity
。该innodb_io_capacity_max
值定义了此类情况下 I/O 容量的上限,因此 I/O 活动的峰值不会消耗服务器的整个 I/O 容量。
该innodb_io_capacity
设置适用于所有缓冲池实例。刷新脏页时,I/O 容量在缓冲池实例之间平均分配。