2025年9月25日: PostgreSQL 18 釋出!
支援的版本: 當前 (18) / 17 / 16 / 15 / 14 / 13
開發版本: devel
不支援的版本: 12 / 11 / 10 / 9.6 / 9.5

pg_rewind

pg_rewind — 將一個 PostgreSQL 資料目錄與另一個從它分叉出來的資料目錄同步

概要

pg_rewind [選項...] { -D | --target-pgdata } 目錄 { --source-pgdata=目錄 | --source-server=連線字串 }

描述

pg_rewind 是一個用於在 PostgreSQL 叢集的邏輯時間線(timeline)發生分叉後,將一個 PostgreSQL 叢集與同一個叢集的另一個副本進行同步的工具。一個典型的場景是在主備切換後,將舊的主伺服器重新上線,使其成為跟隨新主伺服器的備伺服器。

成功執行 rewind 操作後,目標資料目錄的狀態類似於源資料目錄的基礎備份。與執行新的基礎備份或使用 rsync 等工具不同,pg_rewind 不需要比較或複製叢集中未更改的關聯塊。它只複製現有關聯檔案中已更改的塊;所有其他檔案,包括新的關聯檔案、配置檔案和 WAL 段,都會被完整複製。因此,當資料庫很大而叢集之間只有一小部分塊不同時,rewind 操作會比其他方法快得多。

pg_rewind 會檢查源叢集和目標叢集的時間線歷史,以確定它們分叉的點,並期望在目標叢集的 pg_wal 目錄中找到一直追溯到分叉點的 WAL。分叉點可能位於目標時間線、源時間線或它們的共同祖先上。在典型的切換場景中,目標叢集在分叉後很快關閉,這不是問題。但如果目標叢集在分叉後運行了很長時間,其舊的 WAL 檔案可能已不再存在。在這種情況下,您可以手動將它們從 WAL 歸檔複製到 pg_wal 目錄,或者執行帶有 -c 選項的 pg_rewind 來自動從 WAL 歸檔檢索它們。pg_rewind 的使用不限於切換場景,例如,可以將備伺服器提升為主伺服器,執行一些寫事務,然後再進行 rewind 操作使其重新成為備伺服器。

執行 pg_rewind 後,需要完成 WAL 重放(replay),資料目錄才能處於一致狀態。當目標伺服器再次啟動時,它將進入歸檔恢復(archive recovery)模式,並重放從分叉點之前最後一個檢查點開始由源伺服器生成的全部 WAL。如果在執行 pg_rewind 時源伺服器上的一些 WAL 已不再可用,因此無法被 pg_rewind 會話複製,那麼在目標伺服器啟動時必須提供這些 WAL。這可以透過在目標資料目錄中建立 recovery.signal 檔案,並在 postgresql.conf 中配置合適的 restore_command 來實現。

pg_rewind 要求目標伺服器的 postgresql.conf 中啟用 wal_log_hints 選項,或者在初始化叢集時啟用了資料校驗和(data checksums)。這兩個選專案前預設都未開啟。full_page_writes 也必須設定為 on,但它預設是啟用的。

警告:Rewind 過程中的故障

如果在處理過程中 pg_rewind 發生故障,則目標資料資料夾可能處於無法恢復的狀態。在這種情況下,建議執行一個新的全新備份。

由於 pg_rewind 會完整地複製源伺服器的配置檔案,因此在重啟目標伺服器之前,可能需要糾正用於恢復的配置,特別是如果目標伺服器將重新作為源伺服器的備伺服器。如果在 rewind 操作完成後重啟伺服器,但未配置恢復,目標伺服器可能會再次與主伺服器分叉。

pg_rewind 會立即失敗,如果它發現無法直接寫入的檔案。這可能發生在源伺服器和目標伺服器使用相同的讀取-寫入 SSL 金鑰和證書檔案對映時。如果目標伺服器存在此類檔案,建議在執行 pg_rewind 之前將其刪除。執行 rewind 後,其中一些檔案可能已從源伺服器複製過來,在這種情況下,可能需要刪除複製的資料,並恢復 rewind 前使用的連結集。

選項

pg_rewind 接受以下命令列引數

-D 目錄
--target-pgdata=目錄

此選項指定了與源同步的目標資料目錄。執行 pg_rewind 之前,目標伺服器必須已乾淨關閉。

--source-pgdata=目錄

指定源伺服器資料目錄的檔案系統路徑,用於與目標伺服器同步。此選項要求源伺服器已乾淨關閉。

--source-server=連線字串

指定一個 libpq 連線字串,用於連線到源 PostgreSQL 伺服器以與目標伺服器進行同步。連線必須是正常的(非複製)連線,且使用的角色擁有足夠的許可權在源伺服器上執行 pg_rewind 所使用的函式(參見“注意事項”部分獲取詳細資訊),或者是一個超級使用者角色。此選項要求源伺服器正在執行並接受連線。

-R
--write-recovery-conf

在輸出目錄中建立 standby.signal 檔案,並將連線設定追加到 postgresql.auto.conf 檔案中。僅當在連線字串或 環境變數 中明確指定了 dbname 時,才會記錄 dbname--source-server 選項與此選項一起使用是必需的。

-n
--dry-run

執行除實際修改目標目錄之外的所有操作。

-N
--no-sync

預設情況下,pg_rewind 會等待所有檔案安全寫入磁碟。此選項會導致 pg_rewind 在不等待的情況下返回,這樣更快,但這意味著後續的作業系統崩潰可能會導致資料目錄損壞。通常,此選項對於測試很有用,但不應在生產環境中使用。

-P
--progress

啟用進度報告。啟用此選項後,在從源叢集複製資料時將顯示近似的進度報告。

-c
--restore-target-wal

使用目標叢集配置中定義的 restore_command 從 WAL 歸檔中檢索 WAL 檔案,前提是這些檔案在 pg_wal 目錄中不再可用。

--config-file=檔名

使用指定的伺服器主配置檔案作為目標叢集的配置檔案。當 pg_rewind 在此叢集上內部使用 postgres 命令執行 rewind 操作時(當使用 -c/--restore-target-wal 選項檢索 restore_command 以及強制完成崩潰恢復時),此選項會產生影響。

--debug

列印詳細的除錯輸出,這主要對除錯 pg_rewind 的開發者有用。

--no-ensure-shutdown

pg_rewind 要求在 rewind 之前目標伺服器必須乾淨關閉。預設情況下,如果目標伺服器沒有乾淨關閉,pg_rewind 會以單使用者模式啟動目標伺服器以先完成崩潰恢復,然後停止它。透過傳遞此選項,pg_rewind 將跳過此步驟,並在伺服器未乾淨關閉時立即報錯。在這種情況下,使用者需要自行處理。

--sync-method=method

當設定為 fsync(預設值)時,pg_rewind 會遞迴開啟並同步資料目錄中的所有檔案。檔案搜尋將遵循 WAL 目錄和每個已配置表空間(tablespace)的符號連結。

在 Linux 上,還可以使用 syncfs 來要求作業系統同步包含資料目錄、WAL 檔案和每個表空間的整個檔案系統。有關使用 syncfs 時需要注意的注意事項,請參閱 recovery_init_sync_method

當使用 --no-sync 時,此選項無效。

-V
--version

顯示版本資訊,然後退出。

-?
--help

顯示幫助資訊,然後退出。

環境變數

當使用 --source-server 選項時,pg_rewind 還會使用 libpq 支援的環境變數(參見 第 32.15 節)。

環境變數 PG_COLOR 指定是否在診斷訊息中使用顏色。可能的值為 alwaysautonever

註釋

當使用線上叢集作為源執行 pg_rewind 時,可以使用一個具有足夠許可權在源叢集上執行 pg_rewind 所需函式的角色,而不是超級使用者。下面是建立一個名為 rewind_user 的角色的方法。

CREATE USER rewind_user LOGIN;
GRANT EXECUTE ON function pg_catalog.pg_ls_dir(text, boolean, boolean) TO rewind_user;
GRANT EXECUTE ON function pg_catalog.pg_stat_file(text, boolean) TO rewind_user;
GRANT EXECUTE ON function pg_catalog.pg_read_binary_file(text) TO rewind_user;
GRANT EXECUTE ON function pg_catalog.pg_read_binary_file(text, bigint, bigint, boolean) TO rewind_user;

工作原理

基本思想是將所有檔案系統級別的更改從源叢集複製到目標叢集。

  1. 掃描目標叢集的 WAL 日誌,從源叢集時間線歷史分叉之前的最後一個檢查點開始。對於每個 WAL 記錄,記錄被觸及的每個資料塊。這將生成一個列表,包含在源叢集分叉後目標叢集中更改的所有資料塊。如果一些 WAL 檔案不再可用,嘗試使用 -c 選項重新執行 pg_rewind 來在 WAL 歸檔中搜索丟失的檔案。

  2. 將所有這些更改過的塊從源叢集複製到目標叢集,可以透過直接檔案系統訪問(--source-pgdata)或 SQL(--source-server)來實現。現在,關聯檔案將處於一個狀態,該狀態等同於源叢集和目標叢集 WAL 時間線分叉之前的最後一個已完成檢查點時刻,再加上該分叉點之後在目標叢集上發生的任何塊更改的源叢集當前狀態。

  3. 複製所有其他檔案,包括新的關聯檔案、WAL 段、pg_xact 和配置檔案,從源叢集到目標叢集。與基礎備份類似,來自源叢集的資料複製中會省略 pg_dynshmem/pg_notify/pg_replslot/pg_serial/pg_snapshots/pg_stat_tmp/pg_subtrans/ 目錄的內容。檔案 backup_labeltablespace_mappg_internal.initpostmaster.optspostmaster.pid.DS_Store,以及任何以 pgsql_tmp 開頭的檔案或目錄,都會被省略。

  4. 建立一個 backup_label 檔案,以便在切換(failover)時建立的檢查點開始 WAL 重放,並配置 pg_control 檔案,將其最小一致性 LSN(Log Sequence Number)設定為從活動源 rewind 時 pg_current_wal_insert_lsn() 的結果,或從已停止源 rewind 時最後一個檢查點 LSN。

  5. 在啟動目標伺服器時,PostgreSQL 會重放所有必需的 WAL,從而使資料目錄處於一致狀態。

提交更正

如果您在文件中發現任何不正確、與您的使用經驗不符或需要進一步解釋的內容,請使用 此表單 來報告文件問題。