髒頁的定義
- 記憶體中的資料頁跟磁碟中的資料頁不一致的時候,這些資料頁就是髒頁
需要重新整理髒頁的場景
- InnoDB的redo log寫滿了
- 系統記憶體不足
- 系統空閒時(不影響效能)
- MySQL正常關閉過程(不影響效能)
重新整理髒頁的場景分析
場景1 - InnoDB的redo log寫滿了
這種情況要儘量避免,出現這種情況的時候,整個系統就不能再接受更新了,所有更新都將被阻塞
場景2 - 系統記憶體不足
記憶體不足是指InnoDB中的buffer pool的剩餘記憶體不足
buffer pool中的資料頁有三種狀態:
- 還未使用
- 使用後,仍然是乾淨頁
- 使用後,變成髒頁
資料頁從磁碟讀入記憶體時,需要向buffer_pool申請一個資料頁,buffer_pool會根據LRU演算法淘汰一個資料頁,如果淘汰的資料頁是髒頁,那麼會先將髒頁資料重新整理到磁碟中,然後才複用資料頁;如果一個查詢要淘汰掉的髒頁太多了,會導致查詢的響應時間變長
- InnoDB從磁碟中載入資料的時候,是以資料頁作為單位的,預設資料頁大小為16K,通過引數innodb_page_size可以設定資料頁的大小(從MySQL5.6開始可以通過這個引數調整,但是5.6以前,需要修改原始碼中的UNIV_PAGE_SIZE相關值)
- buffer_pool中的LRU演算法是改進後的URL演算法,目的是為了InnoDB載入冷資料的同時,可以保持buffer_pool的記憶體命中率
- buffer_pool是InnnoDB的緩衝池,裡面包含了各種buffer,例如change_buffer、join_buffer等等
設定髒頁重新整理策略
- 想要InnoDB以合理的速度去重新整理髒頁,首先需要先告訴InnoDB,所在主機的磁碟IO能力,然後通過設定innodb_io_capacity引數,指定InnoDB重新整理髒頁的速度上限
- InnDB根據兩個因素來判斷重新整理髒頁的速度
- buffer_pool中的髒頁比例 innodb_buffer_pool_pages_dirty/innodb_buffer_pool_pages_total
- redo log中的剩餘空間
鄰居連坐機制
刷髒頁的額時候,如果發現髒頁旁邊的資料頁(鄰居)也是髒頁,就會將這個鄰居也一併刷掉,以此類推
-
通過引數innodb_flush_neighbors控制該機制
- innodb_flush_neighbors = 1表示啟用
- innodb_flush_neighbors = 0表示禁用
-
連坐機制對於機械硬碟是很有意義的,機械硬碟IOPS比較低,通過連坐機制可以減少大量隨機IO
-
對於SSD裝置,建議設定innodb_flush_neighbors = 0,因為SSD的IOPS很高
MySQL教程推薦
- 極客時間 - 《MySQL實戰45講》
- 《高效能MySQL第三版》