17.8.3.5 配置缓冲池刷新
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
值。
还有一些变量可以 fine-tuning 缓冲池刷新行为:
-
innodb_flush_neighbors
变量定义了是否在刷新缓冲池页面时也刷新同一存储空间中的脏页。-
默认设置为0,禁用
innodb_flush_neighbors
。同一存储空间中的脏页不被刷新。这一设置对于非旋转存储设备(SSD)设备推荐,因为 seek 时间不是一个重要因素。 -
设置为1 则刷新连续的脏页在同一存储空间中。
-
设置为2 则刷新同一存储空间中的脏页。
在传统的HDD存储设备上存储表数据时,flush邻近页面一次可以减少I/O开销(主要是磁盘寻道操作),与在不同时间flush单个页面相比。对于SSD存储的表数据,寻道时间不是一个重要因素,可以禁用这个设置以spread out写操作。
-
-
innodb_lru_scan_depth
变量指定每个缓冲池实例中页面清洁线程在buffer pool LRU列表中扫描的深度,以查找脏页以flush。这是一个背景操作,page cleaner线程每秒执行一次。一个小于默认值的设置通常适合大多数工作负载。一个高于必要的值可能会影响性能。只有在有空闲I/O容量的情况下才考虑增加该值。反之,如果写入密集型工作负载饱和了您的I/O容量,特别是在大缓冲池的情况下,降低该值。
在调整
innodb_lru_scan_depth
时,从低值开始,逐渐增加设置的目的是尽量少见零免费页。同时,在更改缓冲池实例数量时,也要考虑调整innodb_lru_scan_depth
,因为innodb_lru_scan_depth
*innodb_buffer_pool_instances
定义了每秒page cleaner线程执行的工作量。
变量innodb_flush_neighbors
和innodb_lru_scan_depth
主要是为写入密集型工作负载设计的。随着大量DML活动,如果flush不是足够-aggressive,或者如果flush太过-aggressive,磁盘写入可能会饱和I/O能力。理想的设置取决于您的工作负载、数据访问模式和存储配置(例如,是否将数据存储在HDD或SSD设备上)。
InnoDB
使用自适应刷新算法来动态调整刷新率,以根据redo日志生成速度和当前刷新率来平滑整体性能。自动调整刷新率可以避免由于缓冲池刷新活动对I/O可用容量的影响而导致的突然降低。
写入密集型工作负载可能会导致sharp检查点,例如,当InnoDB
想要重用日志文件的一部分时,所有dirty页面中的redo entries都需要被刷新。如果日志文件满了,sharp检查点将发生,导致暂时的降低。即使innodb_max_dirty_pages_pct
阈值未被达到,也可能会出现这种情况。
自适应刷新算法可以避免这些场景,通过跟踪缓冲池中的dirty页面数量和redo日志记录生成率来决定每秒要刷新多少dirty页面,从而管理突然的工作负载变化。
变量innodb_adaptive_flushing_lwm
定义了redo日志容量的低水位标记。当该阈值被跨越时,即使变量innodb_adaptive_flushing
被禁用,自适应刷新仍然启用。
内部基准测试表明,该算法不仅能够保持长时间的吞吐量,还可以显著地提高总体吞吐量。然而,自适应刷新可能会对工作负载的I/O模式产生significant影响,并且在所有情况下都不是合适的选择。在redo日志即将满时,它给出的最大的好处。如果自适应刷新不适用于您的工作负载特征,您可以禁用它。自适应刷新由innodb_adaptive_flushing
变量控制,该变量默认启用。
innodb_flushing_avg_loops
定义了InnoDB
保留之前计算的刷新状态快照的迭代次数,控制自适应刷新对前景工作负载变化的响应速度。高innodb_flushing_avg_loops
值意味着InnoDB
保留之前计算的快照更长时间,自适应刷新响应速度更慢。在设置高值时,请确保redo日志利用率不超过75%(异步刷新开始的硬编码限制),并且innodb_max_dirty_pages_pct
阈值保持脏页数量在合适的工作负载水平。
具有稳定工作负载、较大日志文件大小(innodb_log_file_size
)和小的峰值波动,不会达到75%日志空间利用率的系统,应该使用高innodb_flushing_avg_loops
值,以保持flushing尽可能顺滑。对于具有极端负载峰值或日志文件不提供很多空间的系统,较小的值可以使flushing紧密跟踪工作负载变化,并避免达到75%日志空间利用率。
请注意,如果flushing落后,buffer pool flush rate可能会超过innodb_io_capacity
设置定义的I/O可用能力。在这种情况下,innodb_io_capacity_max
值定义了在I/O活动突然增加时I/O可用能力的上限,以避免服务器的整个I/O可用能力被消耗。
innodb_io_capacity
设置适用于所有buffer pool实例。当脏页被flush时,I/O可用能力将等分地分配给buffer pool实例。
变量innodb_idle_flush_pct
限制了buffer pool在空闲期限内的flush速度,这些空闲期限是指数据库页面未被修改的时间。其值将被解释为innodb_io_capacity
(定义InnoDB
可用的I/O操作数每秒)的百分比。默认值为100,即innodb_io_capacity
的100%。要限制空闲期限内的flush速度,设置innodb_idle_flush_pct
小于100。
在空闲期限内限制页面flush可以帮助延长固态存储设备的使用寿命。在限制页面flush期间可能出现的一些副作用包括:在长时间空闲后服务器关闭时的更长时间,和在服务器故障发生时的更长恢复时间。