PostgreSQL的wal_buffers

T1YSL發表於2022-12-12

image.png

1、什麼是wal buffer?

wal buffer是預寫日誌(wal)緩衝區

2、wal buffer的作用是什麼

用於還未寫入磁碟的 WAL 資料的共享記憶體。

每次變更事務提交時候,需要將變更事務日誌落盤,在PG中為了提高效能,並非採用實時flush到磁碟,而是在PG中提供 XLog Buffer空間臨時儲存提交的事務日誌,然後定期flush到磁碟。一旦任何給定的 8kB 緩衝區的內容持久地儲存在磁碟上,就可以重複使用該緩衝區 。由於插入和寫入都是順序的,因此 WAL 緩衝區實際上是一個環形緩衝區 。緩衝區填滿時效能會受到影響:在當前重新整理完成之前,無法再插入WAL 。當synchronous_commit未關閉時,每個事務提交都會等待其 WAL 記錄重新整理到磁碟,從而減輕了wal緩衝區的影響。

如果一個事務更新大型記錄或大量行,或者大量客戶端併發執行更新事務,導致WAL緩衝區被填滿,則它需要去刷磁碟而不能插入WAL,進而影響了wal的寫入次數,則適當增加wal_buffers ,可能會提高效能。一般當單事務的資料修改量很大,產生的日誌大於wal_buffers時,可適當調大該值。當有比較多的併發短事務時,可與引數commit_delay及commit_siblings連用,並適當調大該值。

但是在每次事務提交時,WAL 緩衝區的內容被寫到磁碟,因此太大的值可能也不是個明智之舉。 總的來說,資料庫引數的調優並不能為了迎合某一階段的SQL或者幾條SQL。必須從資料庫的整體去考量,從整體去得出一個值,而且不要去輕易頻繁改動,否則不利於資料庫的穩定性,而且也有可能會影響業務的連續性和使用者體驗。

曾有人測試過在一個系統進行調優,發現wal_buffers=64MB 的效能比 wal_buffers=16MB 翻了一番。但是也有的人在調優的時候,無論怎麼搭配引數,效能都沒有比原本預設的1/32的自動調整的方式高出10%。因此更多還是看實際的場景,SQL情況,以及併發等。對於這個引數,在具有大量併發的環境,可能有一定的最佳化空間,嘗試稍微高一點的值,特別是如果你有頻繁的檢查點(主要指檢查點之後防止在崩潰時頁裂的full page write,這些全頁寫會非常快速地填滿WAL 緩衝區)。

曾經看過一篇文章,評論裡有人想根據在一段時間內寫入 WAL 的資料位元組數來做估算。
image.png

類似如下的方式,感興趣的可以試試。
image.png

3、wal_buffers預設是怎麼自動計算的

XLog Buffer的大小預設由引數 wal_buffers決定,當這個引數設定為-1時候,PG會根據 shared_bufferswal_segment_size引數自動計算而得到。

image.png

正常情況下,wal_buffers設定為-1的時候,wal_buffers的大小為shared_buffers的1/32,這個比例也是Gregory Smith之前給出的建議(Gregory Smith是國際PostgreSQL服務公司2ndQuadrant在美國的首席顧問),在程式碼裡是由 NBuffers/32 來展現的,因此透過對應比例調整shared_buffers其實可以獲得適當的最佳化,而其實更高的值有時也可以顯著提高效能 ,主要還是看實際的使用場景。

-B NBuffers 是可以作為 Postgres 執行時候的命令列引數所設定的。

image.png

下邊是這個引數的解釋

-B nbuffers

Sets the number of shared buffers for use by the server processes. The default value of this parameter is chosen automatically by initdb. Specifying this option is equivalent to setting the shared_buffers configuration parameter.

nbuffers和shared_buffers是具備換算關係的,兩者計算的位元組數是一致的,以shared_buffers的單位為MB為例,具體的換算為 :

nbuffers=(shared_buffers*1024)/block_size

舉個例子在進行換算的時候,比如10MB的shared_buffers,它佔用的位元組是shared_buffers*1024*1024,
而nbuffers佔用的是 nbuffers*block_size*1024,所以我們想給shared_buffers設定為10MB,
透過計算nbuffers=(shared_buffers*1024)/block_size=1280,我們透過如下啟動postrges的時候
指定-B來進行檢驗。最終的結果和我們的換算是一致的。

image.png


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69990629/viewspace-2927749/,如需轉載,請註明出處,否則將追究法律責任。

相關文章