MySQL参数解析innodb_flush_neighbors

2023年 8月 15日 58.5k 0

innodb_flush_neighbors 参数是InnoDB用来控制buffer pool刷脏页时是否把脏页邻近的其他脏页一起刷到磁盘,在传统的机械硬盘时代,打开这个参数能够减少磁盘寻道的开销,显著提升性能。

  • 取值范围:0,1,2
  • 默认值:5.7版本为1, 8.0版本为0

含义:

  • 设置为0时,表示刷脏页时不刷其附近的脏页。
  • 设置为1时,表示刷脏页时连带其附近毗连的脏页一起刷掉。
  • 设置为2时,表示刷脏页时连带其附近区域的脏页一起刷掉。1与2的区别是2刷的区域更大一些。

如果MySQL服务器磁盘是传统的HDD存储设备,打开该参数,能够减少I/O磁盘寻道的开销,提高性能,而对于SSD设备,寻道时间的性能影响很小,关闭该参数,反而能够分散写操作,提高数据库性能。由于SSD设备的普及,MySQL 8.0 将该参数的默认值由1调整为0。

innodb_flush_neighbors参数源码分析:

源码版本:5.7.19

在源码中,innodb_flush_neighbors 参数对应的变量为srv_flush_neighbors,这是一个全局变量,默认值为1,如下:

ulong srv_flush_neighbors = 1;

整个代码中,用到变量 srv_flush_neighbors 的地方只有一个,那就是函数 buf_flush_try_neighbors(),该函数位于源码文件:storage/innobase/buf/buf0flu.cc

buf_flush_try_neighbors() 函数主要逻辑,如下:

static ulint buf_flush_try_neighbors(
      const page_id_t&  page_id,
      buf_flush_t       flush_type,
      ulint             n_flushed,
      ulint             n_to_flush)
{

if (UT_LIST_GET_LEN(buf_pool->LRU) < BUF_LRU_OLD_MIN_LEN
|| srv_flush_neighbors == 0) {

// [low, high] 区间不包含邻近的页面
low = page_id.page_no();
high = page_id.page_no() + 1;

}else{
// [low, high] 区间包含邻近的页面
low = (page_id.page_no() / buf_flush_area) * buf_flush_area;
            high = (page_id.page_no() / buf_flush_area + 1) * buf_flush_area;

if (srv_flush_neighbors == 1) {
...
// 根据 [low, high] 区间内的页是否可以刷盘,来进一步缩小 [low, high] 区间
}
}

...
// 根据 [low, high] 区间进行脏页刷盘
}

buf_flush_try_neighbors() 函数根据 [low, high] 区间来刷脏页。

  • 当 srv_flush_neighbors 为 0时, [low, high] 只包含一个页面。
  • 当 srv_flush_neighbors 为 1时, [low, high] 包含邻近的页面,页面数小于等于变量值buf_flush_area。
  • 当 srv_flush_neighbors 为 2时, [low, high] 包含邻近的页面,页面数等于变量值buf_flush_area。

相关文章

Oracle如何使用授予和撤销权限的语法和示例
Awesome Project: 探索 MatrixOrigin 云原生分布式数据库
下载丨66页PDF,云和恩墨技术通讯(2024年7月刊)
社区版oceanbase安装
Oracle 导出CSV工具-sqluldr2
ETL数据集成丨快速将MySQL数据迁移至Doris数据库

发布评论