1. 程式人生 > 其它 >mysql 檢視 髒頁_MySQL:刷髒頁

mysql 檢視 髒頁_MySQL:刷髒頁

mysql 刷髒頁

···
mysql> select @@innodb_flush_neighbors;
+--------------------------+
| @@innodb_flush_neighbors |
+--------------------------+
| 1 |
+--------------------------+
1 row in set (0.00 sec)

mysql>
···

  1. 髒頁,乾淨頁

當記憶體資料頁和磁碟資料頁上的內容不一致時,我們稱這個記憶體頁為髒頁;

記憶體資料寫入磁碟後,記憶體頁上的資料和磁碟頁上的資料就一致了,我們稱這個記憶體頁為乾淨頁。

  1. 刷髒頁的時機

2.1 redo log

redo log 是迴圈寫的,當redo log 寫滿了,即 write pos 追上了 checkpoint 時,此時沒有空間記錄 redo log,就需要將 checkpoint 向前推進,推進的這部分日誌對應的髒頁就需要刷入磁碟。

此時所有的更新全部阻塞,此時寫效能跌為0,必須等待刷一部分髒頁後才能繼續更新,這種情況要儘量避免;

2.2 系統記憶體

當系統記憶體不足時,就需要將一部分資料頁淘汰掉,如果淘汰的是髒頁,就需要先將髒頁刷入磁碟。

當淘汰的髒頁過多時,會導致查詢的響應時間變長;

2.3 MySQL認為空閒的時間

不存在效能問題;

2.4 MySQL正常關閉之前,會把記憶體中所有的髒頁刷入磁碟

不存在效能問題;

  1. 刷髒頁的控制策略

3.1 正確伺服器的IO能力

innodb_io_capacity引數表示機器的磁碟能力,根據機器能力合理設定該引數的值;

3.2 刷髒頁的速度

InnoDB的刷盤速度主要參考兩個引數:髒頁比例和redo log 的寫盤速度;

innodb_max_dirty_pages_pct是髒頁比例上限,預設值為75%;

InnoDB根據當前的髒頁比例算出一個值M1;

InnoDB每次寫入redo log 有一個序號,根據當前序號和checkpoint之間的差值算出一個值M2;

之後引擎取M1和M2之間(M1和M2都是0-100之間的數)的較大值除以100乘以innodb_io_capacity,這就是刷髒頁的速度;

3.3 刷髒頁機制

當一個查詢請求執行過程中需要先flush一個髒頁時,如果髒頁的旁邊也是髒頁,此時引擎會將相鄰的髒頁也刷掉,直到下一個資料頁不是髒頁為止;

該機制通過引數 innodb_innodb_flush_neighbors 控制,值為0時表示只刷自己,值為1時則有連坐效果;

相關資源:Mysql髒頁flush及收縮表空間原理解析_mysql空間收縮,mysql收縮...
————————————————
https://blog.csdn.net/weixin_33773734/article/details/113156521

而MySQL中的一個機制,可能讓你的查詢會更慢:在準備刷一個髒頁的時候,如果這個資料頁旁邊的資料頁剛好是髒頁,就會把這個“鄰居”也帶著一起刷掉;而且這個把“鄰居”拖下水的邏輯還可以繼續蔓延,也就是對於每個鄰居資料頁,如果跟它相鄰的資料頁也還是髒頁的話,也會被放到一起刷。

在InnoDB中,innodb_flush_neighbors 引數就是用來控制這個行為的,值為1的時候會有上述的“連坐”機制,值為0時表示不找鄰居,自己刷自己的。

找“鄰居”這個優化在機械硬碟時代是很有意義的,可以減少很多隨機IO。機械硬碟的隨機IOPS一般只有幾百,相同的邏輯操作減少隨機IO就意味著系統性能的大幅度提升。

而如果使用的是SSD這類IOPS比較高的裝置的話,我就建議你把innodb_flush_neighbors的值設定成0。因為這時候IOPS往往不是瓶頸,而“只刷自己”,就能更快地執行完必要的刷髒頁操作,減少SQL語句響應時間。

在MySQL 8.0中,innodb_flush_neighbors引數的預設值已經是0了