天天看點

【轉】Postgres間隔大量寫IO的解決辦法概述OS層面資料庫層面

轉自:https://www.cnblogs.com/lykops/p/8263093.html

概述

為了保證資料可靠性,同時還要保證好的讀寫性能,以及讀寫的一緻性,經過多年的積累,REDO日志,shared buffer等基本成為關系型資料庫的标配。postgres也不例外。

為了保證資料的可靠性,通常在将髒頁面寫入硬碟前,先将wal日志先寫入硬碟,然後将修改的資料異步分批寫入。

為了保證好的讀寫性能,修改的資料先寫到shared buffer中,而不是直接寫入硬碟,因為資料頁很離散(修改的資料分布在不同的表中)。資料庫會把wal日志順序寫入硬碟中。

postgres提供兩種方式寫:write和fsync。差別是:

write:資料庫會将buffer中的髒頁根據寫入政策将老化的髒頁面寫到OS,OS再根據自己的排程算法将髒頁寫入硬碟。
fsync:資料庫直接調用OS的fsync函數,直接寫入硬碟。
           

OS層面

涉及到幾個核心參數,同時還涉及到檔案系統。

dirty_background_ratio

設定方法

1、修改systctl:vm.dirty_background_ratio
2、修改檔案/proc/sys/vm/dirty_background_ratio
           

含義

在嘗試執行writeback操作(即OS觸發background flush線程刷髒頁)之前記憶體髒頁面比例。
控制檔案系統的pdflush程序,在何時重新整理磁盤。
機關是百分比,當寫緩沖使用到系統記憶體多少時,pdflush開始向磁盤寫出資料。
增大之會使用更多系統記憶體用于磁盤寫緩沖,也可以極大提高系統的寫性能。
但當需要持續、恒定的寫入場合時,應該降低其數值。預設值5。
           

dirty_expire_centisecs

設定方法

1、修改systctl:vm.dirty_writeback_centisecs
2、修改檔案/proc/sys/vm/dirty_expire_centisecs
           

含義

background flush線程将存活時間超過該值的髒頁刷盤(類似LRU)。
資料可以保持為dirty狀态的最大時間,超過該值pdflush程序就開始考慮寫到磁盤中去。
機關是1/100s。預設30000,也就是30s。
對于特别重載的寫操作來說,這個值适當縮小也是好的,但也不能縮小太多,因為縮小太多也會導緻IO提高太快。
建議設定為1500,也就是15秒算舊。
           

dirty_ratio

設定方法

1、修改systctl:vm.dirty_ratio
2、修改檔案/proc/sys/vm/dirty_ratio
           

含義

控制檔案系統的檔案系統寫緩沖區的大小,機關是百分比。
當髒頁比例達到該值,使用者程序在調用write時,會觸發flush磁盤的操作。表示當寫緩沖使用到系統記憶體多少時,開始向磁盤寫出資料。
當一個任務(或者程序)在髒頁面過多的環境中執行檔案寫操作時,如果髒頁面占用總記憶體的百分比高于dirty_ratio值,那麼系統就執行髒頁面寫入硬碟操作。
增大會使用更多系統記憶體用于磁盤寫緩沖,也可以極大提高系統的寫性能。
但當需要持續、恒定的寫入場合時,應該降低其數值,預設值10。
           

dirty_writeback_centisecs

設定方法

1、修改systctl:vm.dirty_writeback_centisecs
2、修改檔案/proc/sys/vm/dirty_writeback_centisecs
           

含義

控制核心的髒資料重新整理程序pdflush的運作間隔,執行background flush線程的喚醒間隔。
機關是1/100s。預設值是500,也就是5s。
适當減少該值有寫操作削峰作用,如果系統是持續地寫入動作,那麼降低該值比較好,可以把尖峰寫操作削平成多次寫操作。
該參數值應小于dirty_expire_centisecs,但太小I/O太頻繁,反而使系統性能下降。
據說1:6 (dirty_expire_centisecs: dirty_writeback_centisecs )的比例比較好。
           

dirty_background_bytes

如果記憶體非常大,當觸發背景線程刷髒頁時,可能需要刷很多髒頁,導緻尖銳的IO需求。

可以通過修改核心參數vm.dirtybackgroundbytes達到削尖的目的。

vm.dirtybackgroundbytes = 102400000 當髒頁數達到了100MB,系統觸發background flush線程刷髒頁

資料庫層面

wal日志寫入方式fsync

fsync = on   
開啟後強制把wal日志同步更新到磁盤,可以保證資料庫将在OS或者硬體崩潰的後恢複到一個一緻的狀态。
雖然關閉,可以提升資料庫性能,但無法保證資料庫崩潰後資料一緻性。
通常情況下需要打開這個參數,除非能經受掉電或硬體故障帶來的資料丢失,否則不要關閉。
           

backend_flush_after

機關:BLCKSZ
當某backend process髒資料超過配置門檻值時,觸發調用OS sync_file_range,告訴os backend flush線程異步刷盤。  
進而削減os dirty page堆積。  
           

bgwriter_flush_after

機關:BLCKSZ
當bgwriter process髒資料超過配置門檻值時,觸發調用OS sync_file_range,告訴os backend flush線程異步刷盤。  
進而削減os dirty page堆積。  
           

checkpoint_flush_after

機關:BLCKSZ
當checkpointer process髒資料超過配置門檻值時,觸發調用OS sync_file_range,告訴os backend flush線程異步刷盤。  
進而削減os dirty page堆積。  
           

wal_writer_flush_after

機關:BLCKSZ
當wal writer process髒資料超過配置門檻值時,觸發調用OS sync_file_range,告訴os backend flush線程異步刷盤。  
進而削減os dirty page堆積。             

繼續閱讀