資料寫入、WAL 生成、日誌切換 (Switching)、歸檔 (Archive) 到 備份 (Backup) 的完整生命週期:

1. 資料寫入與 WAL 生成 (Data Writing & WAL Generation)

這是資料誕生的第一步,核心原則是「先記帳,後結帳」 (Write-Ahead Logging)**。

  • 寫入緩衝區: 當您執行 INSERTUPDATE 等指令時,PostgreSQL 不會立刻修改硬碟上的資料庫主檔案(Data Files),而是先將這筆異動記錄到記憶體中的 WAL Buffer
  • 強制落盤 (Flush): 當交易提交 (Commit) 時,這條日誌必須立刻被寫入硬碟中 pg_wal 資料夾下的 WAL Segment 檔案
  • 確保安全性: 只要這條日誌進入了 pg_wal,即便下一秒斷電,資料庫重啟後也能透過重播日誌找回資料。
  • 檢查點 (Checkpoint): 只有在 Checkpoint 發生時,記憶體中實際修改的數據(Dirty Buffers)才會真正寫入資料庫的主檔案。此時,舊的 WAL 就不再需要用於崩潰恢復。

2. 日誌切換與管理 (WAL Switching & Management)

WAL 檔案並不是無限寫在同一個檔案裡,而是有固定大小與輪替機制的。

  • 切換機制 (Switching): 預設每個 WAL 檔案大小為 16MB。當一個檔案寫滿時,PostgreSQL 會進行「切換」,開始寫入下一個序號的檔案。
  • 回收與重命名 (Recycling): 為了節省建立新檔案的 I/O 開銷,PostgreSQL 會將不再需要的舊 WAL 檔案(已過 Checkpoint 且已歸檔者)重新命名為未來的序號,循環使用。
  • 刪除機制: 如果 pg_wal 累積的數量超過設定範圍(如 max_wal_size),且確認已歸檔完成,系統才會物理刪除多餘的檔案。

3. 歸檔傳送 (Archiving)

這是將資料從「本地暫存」轉移到「外部保險箱」的關鍵步驟,由 pgBackRest 擔任搬運工。

  • 觸發傳送: 一旦 WAL 發生「日誌切換 (Switching)」(即寫滿 16MB),PostgreSQL 會立刻執行 archive_command
  • 搬運與壓縮: archive_command 會呼叫 pgbackrest archive-push。pgBackRest 會將該 WAL 檔案進行壓縮,並傳送到遠端的儲存庫(Repo)。
  • 形成連續鏈: 這些歸檔後的 WAL 檔案在 Repo 中依序號排列,只要鏈條不斷,您就擁有從過去到現在的所有變動紀錄。
  • 空窗期風險: 值得注意的是,正在寫入但「還沒寫滿 16MB」的那個 WAL 檔案,通常還不會被傳送到 Archive。如果此時硬碟全毀,這最後一小段資料可能會遺失,除非您設定了 archive_timeout 強制切換。

4. 備份快照 (Backup)

歸檔是「錄影帶」,備份則是「全家福照片」。單靠重播日誌太慢,需要定期建立基礎還原點。

  • 全量備份 (Full Backup): pgBackRest 會拷貝所有的數據主檔案 (Data Files)。這就像拍下一張建築物的完整照片。
  • 建立關聯: 備份完成的那一刻,pgBackRest 會記錄這份備份對應到的 WAL 序號,確立還原時的起點。
  • 差異與增量: 為了節省空間,之後的備份可以只抓取自上次全備份以來有變動的檔案 (Diff/Incr)。

5. 流程總結與隱喻

為了讓這個複雜的流程更容易記憶,我們可以套用之前提到的隱喻:

階段動作隱喻說明關鍵行為
1. 寫入WAL Generation施工日記師傅每砌一塊磚,先在隨身筆記本(記憶體)寫下,然後立刻抄寫到現場日誌本(pg_wal)上。
2. 切換Switching換新本子現場日誌本寫滿了(16MB),師傅換一本新的繼續寫,舊的本子準備封存。
3. 歸檔Archive送往檔案室搬運工(pgBackRest)立刻把寫滿的舊本子拿走,壓縮打包送去遠處的防火檔案室(Repo)。
4. 備份Backup拍攝全景照攝影師每週來一次,拍下整棟建築物目前的樣子(Data Files)。這樣下次要重建時,就不用從打地基開始看日記,直接看照片再補日記即可。

特別提醒: 在災難還原時,如果原始機器的 pg_wal 硬碟沒壞,務必手動將那些「還沒來得及歸檔」的 WAL 檔案拷貝出來,並在還原後放回新機器,這樣才能達成真正的 Zero Data Loss(零資料遺失)

postgreSQL