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 的值。
限制空闲期间的页面刷写有助于延长固态存储设备的使用寿命。限制空闲期间的页面刷写的副作用可能包括在长时间空闲后关闭时间更长,以及在服务器发生故障时恢复时间更长。