天天看點

Write-Ahead Logging (WAL)相關參數配置

Write-Ahead Logging (WAL)是保證資料完整性的标準方法,在大多數關于事務處理的書中都可以找到詳細的描述。

簡單的說,WAL的核心思想是確定資料檔案的更改必須在這些更改被寫入日志之後才能進行。

遵循這個原則,就不需要在每個事物中将資料重新整理到磁盤送出。因為在發生崩潰時,我們能夠使用日志,将沒有寫入到磁盤的任何更改從日志記錄中重新執行(這是前滾恢複,也稱為重做)。

PG資料庫中有很多WAL相關的參數,通過正确的配置能夠提高資料庫的性能。

檢查點

檢查點與WAL有密不可分的聯系。

檢查點是事務序列中的點,在這些事務序列中,需要保證表和索引資料檔案已經使用檢查點之前的所有資訊進行了更新。

在檢查點發生時,将所有髒資料頁重新整理到磁盤,并将一個特殊的檢查點記錄寫入日志檔案。(更改記錄以前被重新整理到WAL檔案中。)

min_wal_size、max_wal_size

在PostgreSQL 10以前版本中存在的checkpoint_segments參數已經消失,原意是指在日志檔案段數量達到設定的最大值時,觸發檢查點。

原來是通過參數checkpoint_segments來直接指定的,而現在通過如下方式計算。(來自網絡)

target = (double) max_wal_size / (2.0 + CheckPointCompletionTarget);

    /* round down */
    CheckPointSegments = (int) target;

    if (CheckPointSegments < 1)
        CheckPointSegments = 1;           

CheckPoint_Completion_Target 取值範圍是 (0.0,1.0)

是以最終CheckPoint_Segments得到的值範圍是 max_wal_size 的 1/3 ~ 1/2

現在CheckPoint_Segments已經不存在,但是通過兩個參數計算的結果可以得出,在pg_wal檔案數量超過max_wal_size 1/3~1/2的時候,仍然會觸發檢查點。

觸發檢查點的方式

伺服器的checkpointer程序會自動執行檢查點。

  • checkpoint_timeout,當達到該參數的時間時,自動觸發檢查點
  • max_wal_size,當資料量将超過該參數配置的最大值時,自動觸發檢查點
  • 當pg_wal目錄下日志檔案段的數量超過一定數量時
  • 手工執行CHECKPOINT指令

checkpoint_timeout,max_wal_size兩個參數的預設配置分别是5分鐘和1GB。哪個先滿足條件,先觸發執行檢查點。

降低checkpoint_timeout或者max_wal_size的大小,會使檢查點執行的頻率更高。

檢查點的執行對資料庫來說是“相當昂貴”的,首先是因為寫出目前所有髒緩沖區會對IO造成沖擊。其次,如果配置了參數full_page_writes ,它們會導緻額外WAL讀寫壓力。

full_page_writes (boolean)

當啟用此參數時,PostgreSQL伺服器将在檢查點之後第一次修改該頁時将每個磁盤頁的全部内容寫入WAL.

有時這是必需的,因為在作業系統崩潰期間正在進行的讀寫操作可能隻完成了部分,進而導緻磁盤上的頁面包含新舊資料的混合。

通常存儲在WAL中的行級更改資料不足以在崩潰後完全恢複,存儲完整的頁面鏡像可以確定這點;

但這是以增加寫入WAL的資料量為代價的。

checkpoint_warning

當檢查點過于頻繁,兩個檢查點的時間間隔少于參數checkpoint_warning設定的時間時,則會向伺服器日志輸出一條消息,建議增加max_wal_size。

2019-07-23 04:55:45.818 UTC [2185] LOG:  checkpoints are occurring too frequently (24 seconds apart)
2019-07-23 04:55:45.818 UTC [2185] HINT:  Consider increasing the configuration parameter "max_wal_size".           

checkpoint_completion_target

為了避免大量的頁面寫操作增加IO負載,檢查點期間寫髒緩沖區的操作要分散在一段時間内。這個周期由checkpoint_completion_target參數控制。

場景1:

•checkpoint_completion_target=0.5

•checkpoint_timeout = 5min

•00G資料(需要刷進磁盤的資料量)

•1G/s

•100/(0.5*5*60)*1024≈670M/s (資料寫入速度)

場景2:

•checkpoint_completion_target=0.9

•100G資料

•100/(0.9560)*1024≈380M/s

一般伺服器寫入速度為500M/s-1200M/s,checkpoint_completion_target設定的越高的情況下,寫入速度越低,對整體性能的影響越小。反之,較低的值可能會引起I/O峰值,導緻“卡死”的現象。

在同一時間通過檢查點,将所有髒資料頁重新整理到磁盤,會導緻顯著增加I/O的負載。是以,對檢查點活動進行節流,確定I/O從檢查點從開始到完成是在下一個檢查點開始前。這将有效改善檢查點期間的性能下降。

wal_segment_size 日志檔案段的大小

pg_wal目錄下的檔案大小,由該參數決定。該參數隻能在initdb時指定

預設值為16MB

pg_wal目錄中wal段檔案的個數

pg_wal目錄中的WAL段檔案的數量取決于min_wal_size、max_wal_size和以前檢查點周期中生成的WAL的數量。

可以簡單了解為,當伺服器不繁忙時,檔案個數處于一定個數,并循環使用。

即便使用 select pg_switch_wal();指令,也不會增加檔案的個數。

但是當存在大量插入操作的時候,由于沒有及時觸發檢查點,會導緻wal段檔案迅速增長,直到觸發檢查點後重複使用檔案,或在轉為不繁忙時,定期删除不用的wal檔案段。