pg_stat_bgwriter視圖提供了一組共享緩沖區寫入方面性能數據。
=#select * from pg_stat_bgwriter; -[ RECORD 1 ]---------+----------------------------- checkpoints_timed | 15462 #計划檢查點的發生次數,這種檢查點是checkpoint_timeout參數規定的超時達到后系統啟動的checkpoint; checkpoints_req | 148 #非計划檢查點的次數,包含手動的檢查點、xlog(redo日志)檢查點(指當某些數據庫預定的閾值達到時啟動的檢查點,比如WAL已經超出了max_wal_size或者checkpoint_segments,也會觸發xlog ckpt) checkpoint_write_time | 2130524730 #檢查點寫入的總時長 checkpoint_sync_time | 72082 #檢查點同步文件的總時長 buffers_checkpoint | 174657791 #檢查點清理的臟塊 buffers_clean | 0 #bgwriter清理的臟塊數量 maxwritten_clean | 0 #bgwriter清理臟塊的時候達到bgwriter_lru_maxpages后終止寫入批處理的次數,為了防止一次批量寫入太大影響數據塊IO性能,bgwriter每次都有寫入的限制。不過這個參數的缺省值100太小,對於負載較高的數據庫,需要加大; buffers_backend | 24491898 #backend清理的臟塊數量 buffers_backend_fsync | 2 #backend被迫自己調用fsync來同步數據的計數,如果這個計數器不為零,說明當時的fsync隊列已經滿了,存儲子系統肯定出現了性能問題; buffers_alloc | 51275374 #buffer分配的次數 stats_reset | 2021-01-29 14:41:48.97647+08 #上一次RESET這些統計值的時間 =#
PG的bgwriter、checkpointer和backend都可能把臟數據回寫到存儲上。
正常情況下,我們希望大部分的臟數據都是bgwriter寫回存儲的,少量的臟數據是checkpointer寫入的,更少的數據是backend寫入的。因為backend寫入數據是十分高成本的。不過好像事實上並非如此,backend寫入的比例很高。
不過對於DBA來說,應該盡可能地通過調整降低backend回寫臟塊的數量。我們需要分析一下產生這種情況的原因。比如,如果shared buffer上設置偏低,會導致緩沖塊還沒等到bgwriter和checkpointer回寫,就被backend找到並要進行重用那個了。
bgwriter相關的幾個參數:
·bgwriter_delay:bgwriter兩個任務之間的休眠時間的初始值為200毫秒;
·bgwriter_lru_maxpages:每次bgwriter任務寫buffer的最大page數,一旦達到這個數量,bgwriter就結束任務開始休息,也就是說bgwriter休眠200毫秒,然后寫入幾十毫秒就又開始了休息;
·bgwriter_lru_multiplier:這個參數用於評估下一次寫任務的數量,其依據是這段時間內新申請的buffer數量的倍數,如果這個參數乘以新增加buffer分配的數量后小於bgwriter_lru_maxpages,那么有可能下一個寫任務的數量會小於預期的寫入量。將這個參數調大,會增加bgwriter回寫臟塊的數量,不過會增加寫IO壓力,將這個參數調小,可以降低寫IO壓力,不過可能導致backend寫臟塊的比例增加。不同負載的系統中,這個參數的值應該是需要做調整的,而不是只是用缺省值2。如果你發現你的系統的寫IO壓力還不大,但是 bgwriter寫比例偏低,backend寫比例偏高,那么嘗試加大這個參數還是有效的。