天天看點

mysql innodb flus_MySQL參數解析innodb_flush_neighbors

取值範圍: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。