MySQL學習筆記 - 髒頁重新整理策略

小羅希冀發表於2019-05-10

髒頁的定義

  • 記憶體中的資料頁跟磁碟中的資料頁不一致的時候,這些資料頁就是髒頁

需要重新整理髒頁的場景

  1. InnoDB的redo log寫滿了
  2. 系統記憶體不足
  3. 系統空閒時(不影響效能)
  4. 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第三版》

相關文章