InnoDB
在后台执行某些任务,包括从缓冲池中刷新脏页。脏页是指已修改但尚未写入磁盘上的数据文件的页。
缓冲池刷新由页面清理线程执行。页面清理线程的数量由 innodb_page_cleaners
变量控制,该变量的默认值与 innodb_buffer_pool_instances
相同。
当脏页的百分比达到由 innodb_max_dirty_pages_pct_lwm
变量定义的低水位标记值时,将启动缓冲池刷新。默认的低水位标记是缓冲池页面的 10%。innodb_max_dirty_pages_pct_lwm
值为 0 将禁用此早期刷新行为。
innodb_max_dirty_pages_pct_lwm
阈值的目的是控制缓冲池中脏页的百分比,并防止脏页的数量达到由 innodb_max_dirty_pages_pct
变量定义的阈值,该变量的默认值为 90。InnoDB
如果缓冲池中脏页的百分比达到 innodb_max_dirty_pages_pct
阈值,它将积极地刷新缓冲池页。
在配置 innodb_max_dirty_pages_pct_lwm
时,该值应始终低于 innodb_max_dirty_pages_pct
值。
其他变量允许对缓冲池刷新行为进行微调
innodb_flush_neighbors
变量定义从缓冲池中刷新一个页面是否也刷新同一个扩展中的其他脏页面。默认设置 0 将禁用
innodb_flush_neighbors
。同一个扩展中的脏页不会被刷新。此设置推荐用于寻道时间不是重要因素的非旋转存储(SSD)设备。设置为 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% 的日志空间利用率。
请注意,如果刷写落后,缓冲池刷写的速率可能会超过 InnoDB
可用的 I/O 容量,如 innodb_io_capacity
设置所定义。值 innodb_io_capacity_max
定义了在这种情况下 I/O 容量的上限,因此 I/O 活动的峰值不会消耗服务器的全部 I/O 容量。
设置 innodb_io_capacity
适用于所有缓冲池实例。当刷写脏页时,I/O 容量将在缓冲池实例之间平均分配。
变量 innodb_idle_flush_pct
限制了空闲期间的缓冲池刷写速率,空闲期间是数据库页未被修改的时间段。它的值被解释为 innodb_io_capacity
(定义了 InnoDB
可用的每秒 I/O 操作数)的百分比。默认值为 100,即 innodb_io_capacity
值的 100%。要限制空闲期间的刷写,请将 innodb_idle_flush_pct
设置为小于 100。
限制空闲期间的页刷写可以帮助延长固态存储设备的使用寿命。限制空闲期间的页刷写的副作用可能包括在长时间的空闲期之后更长的关闭时间,以及在服务器发生故障时更长的恢复时间。