PostgreSQL之wal日志


先看下進程

 

 

關於持久性的概念

持久性是指,事務提交后,對系統的影響必須是永久的,即使系統意外宕機,也必須確保事務提交時的修改已真正永久寫入到永久存儲中。

簡單來講,我往銀行存了100塊錢,這個存錢流程走完了之后,銀行必須保證我存的100塊錢一直都在,能查詢到,能取出來。

持久性如何實現

最簡單的實現方法,當然是在事務提交后立即刷新事務修改后的數據到磁盤。但是磁盤和內存之間的IO操作是最影響數據庫系統影響時間的,一有事務提交就去刷新磁盤,會對數據庫性能產生較大影響。

WAL機制的引入,即保證了事務持久性和數據完整性,又盡量地避免了頻繁IO對性能的影響。

WalWriter進程

WalWriter進程是一個后端進程,它負責確保WAL文件被正確寫入磁盤,並且它的行為可以在postgresql.conf中設置以下參數進行配置:

#------------------------------------------------------------------------------
# WRITE-AHEAD LOG
#------------------------------------------------------------------------------

# - Settings -

#wal_level = replica                    # minimal, replica, or logical
                                        # (change requires restart)
#fsync = on                             # flush data to disk for crash safety
                                        # (turning this off can cause
                                        # unrecoverable data corruption)
#synchronous_commit = on                # synchronization level;
                                        # off, local, remote_write, remote_apply, or on
#wal_sync_method = fsync                # the default is the first option
                                        # supported by the operating system:
                                        #   open_datasync
                                        #   fdatasync (default on Linux)
                                        #   fsync
                                        #   fsync_writethrough
                                        #   open_sync
#full_page_writes = on                  # recover from partial page writes
#wal_compression = off                  # enable compression of full-page writes
#wal_log_hints = off                    # also do full page writes of non-critical updates
                                        # (change requires restart)
#wal_init_zero = on                     # zero-fill new WAL files
#wal_recycle = on                       # recycle WAL files
#wal_buffers = -1                       # min 32kB, -1 sets based on shared_buffers
                                        # (change requires restart)
#wal_writer_delay = 200ms               # 1-10000 milliseconds
#wal_writer_flush_after = 1MB           # measured in pages, 0 disables
#wal_skip_threshold = 2MB

#commit_delay = 0                       # range 0-100000, in microseconds
#commit_siblings = 5                    # range 1-1000

【wal_level】

控制wal存儲的級別。wal_level確定有多少信息被寫入到WAL。默認值是replica,它添加了WAL歸檔信息,包括只讀服務器(流復制)所需的信息。還可以將其設置為minimal,即只寫入從崩潰或立即關閉中恢復所需的信息。設置為Logical允許在邏輯解碼場景中完成WAL流。


【fsync】

這個參數直接控制日志是否先寫到磁盤。默認值為ON(先寫),這意味着系統應該通過發出wal_sync_method設置的fsync指令,來確保更改確實被刷新到磁盤。雖然關閉fsync通常可以提高性能,其直接隱患是無法保證在系統崩潰時最近的事務能夠得到恢復,也就無法保證相關數據的真實與正確性


【synchronous_commit】

此參數用於配置系統是否等待WAL完全完成后再將狀態信息返回給用戶事務。默認值為ON,表示必須等待WAL完成后才能返回事務狀態信息;配置OFF可以更快地反饋事務狀態,提升性能。


【wal_sync_method】

這個參數控制WAL寫入磁盤的fsync方法。默認值是fsync。可用的值包括open_datasync、fdatasync、fsync_writethrough、fsync、以及open_sync.open_datasync和open_sync,一般采用默認值即可,對於裸設備或文件系統的可選配置,在實際的使用中所帶來的方便相對fsync很有限。

 

【full_page_writes】

指示是否將整個頁面寫入WAL,參數表明是否將整個page寫入WAL。postgresql中數據處理過程中的位置只有內存和WAL中,在內存中的整個page中己包含更新提交的也包含沒有提交的,如果不將整個page寫入WAL中,在介質恢復的時候WAL中記錄的數據不足以實現完整的恢復(說白了就是無法實現介質恢復時事務的回滾),寫入整個page。
說到這里似乎更明白了,postgresql中不存在類似oracle的undo文件,postgresql將前滾和回滾所需的數據都寫入到了WAL。不管是否寫入整個page,對數據庫的PITR不影響(文檔也說明了),因為更新提交肯定要寫入了WAL中。


【wal_buffers】

指示了用於存儲WAL數據的內存空間量。系統默認值為64K。此參數還受wal_writer_delay和commit_delay這兩個參數的影響。


【wal_writer_delay】

WalWriter進程的寫入間隔。默認值是200毫秒。如果時間過長,可能會導致WAL緩沖區內存不足;如果時間太短,會導致WAL不斷寫入,增加磁盤I/O負擔。


【wal_writer_flush_after】

當臟數據超過這個閾值時,它將被刷新到磁盤。


【commit_delay】

指示在WAL buffer中存儲已提交的數據的時間。默認值為0毫秒,表示沒有延遲;當它被設置為非零值時,在事務提交后,事務將不會被立即寫入到WAL中,但它仍然存儲在WAL buffer中,等待WalWriter進程定期寫入磁盤。


【commit_siblings】

當事務發出提交請求時,如果數據庫中的事務數量大於commit_sibling的值,事務將等待一段時間(commit_delay值);否則,事務將直接寫入到WAL。系統默認值是5,這個參數還確定了commit_delay的有效性。

 

WAL如何工作

WAL機制實際是在這個寫數據的過程中加入了對應的寫WAL log的過程,步驟一樣是先到Buffer,再刷新到Disk。

Change發生時:

  •  先將變更后內容記入WAL Buffer

  •  再將更新后的數據寫入Data Buffer

Commit發生時:

  •  WAL Buffer刷新到Disk

  •  Data Buffer寫磁盤推遲

Checkpoint發生時:

  •  將所有Data Buffer刷新到磁盤

Change時:

 

 

Commit和Checkpoint時:

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM