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

54.4. 流複製協議 #

要啟動流複製,前端會在啟動訊息中傳送 replication 引數。值為 true (或 onyes1) 的布林值會告知後端進入物理複製 walsender 模式,在此模式下,可以發出下面列出的一組小的複製命令,而不是 SQL 語句。

database 作為 replication 引數的值傳遞,會指示後端進入邏輯複製 walsender 模式,並連線到 dbname 引數中指定的資料庫。在邏輯複製 walsender 模式下,可以發出下面列出的複製命令以及常規 SQL 命令。

無論是在物理複製還是邏輯複製 walsender 模式下,都只能使用簡單查詢協議。

為了測試複製命令,你可以透過 psql 或任何其他使用 libpq 的工具進行復制連線,連線字串包含 replication 選項,例如:

psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;"

然而,通常更有用的方法是使用 pg_receivewal(用於物理複製)或 pg_recvlogical(用於邏輯複製)。

log_replication_commands 啟用時,複製命令會被記錄在伺服器日誌中。

在複製模式下接受的命令是:

IDENTIFY_SYSTEM #

請求伺服器識別自身。伺服器會回覆一個包含四列的單行結果集:

systemid (text)

標識叢集的唯一系統識別符號。可用於檢查用於初始化備用伺服器的基礎備份是否來自同一個叢集。

timeline (int8)

當前時間線 ID。也用於檢查備用伺服器是否與主伺服器一致。

xlogpos (text)

當前的 WAL flush 位置。用於獲取寫入日誌中一個已知的位置,以便從中開始流式傳輸。

dbname (text)

正在連線的資料庫,或為 null。

SHOW name #

請求伺服器傳送執行時引數的當前設定。這類似於 SQL 命令 SHOW

name

執行時引數的名稱。可用引數在 第 19 章 中有詳細說明。

TIMELINE_HISTORY tli #

請求伺服器傳送時間線 tli 的時間線歷史檔案。伺服器會回覆一個包含兩個欄位的單行結果集。雖然欄位被標記為 text,但它們實際上返回原始位元組,不進行編碼轉換。

filename (text)

時間線歷史檔案的檔名,例如 00000002.history

content (text)

時間線歷史檔案的內容。

CREATE_REPLICATION_SLOT slot_name [ TEMPORARY ] { PHYSICAL | LOGICAL output_plugin } [ ( option [, ...] ) ] #

建立物理或邏輯複製槽。有關複製槽的更多資訊,請參閱 26.2.6 節“複製槽”

slot_name

要建立的槽的名稱。必須是有效的複製槽名稱(參見 26.2.6.1 節“查詢和操作複製槽”)。

output_plugin

用於邏輯解碼的輸出外掛的名稱(參見 47.6 節“邏輯解碼輸出外掛”)。

TEMPORARY

指定此複製槽是臨時的。臨時槽不會儲存到磁碟,並在發生錯誤或會話結束時自動刪除。

支援以下選項:

TWO_PHASE [ boolean ]

如果為 true,此邏輯複製槽支援兩階段提交的解碼。使用此選項時,會解碼並傳輸與兩階段提交相關的命令,如 PREPARE TRANSACTIONCOMMIT PREPAREDROLLBACK PREPARED。事務將在 PREPARE TRANSACTION 時進行解碼和傳輸。預設為 false。

RESERVE_WAL [ boolean ]

如果為 true,此物理複製槽會立即預留 WAL。否則,WAL僅在連線到流複製客戶端時預留。預設為 false。WAL只有在流複製客戶端連線時才預留。預設為 false。

SNAPSHOT { 'export' | 'use' | 'nothing' }

決定在初始化邏輯槽時建立的快照應如何處理。'export'(預設值)會將快照匯出供其他會話使用。此選項不能在事務內使用。'use' 會將快照用於當前執行命令的事務。此選項必須在事務中使用,並且 CREATE_REPLICATION_SLOT 必須是該事務中執行的第一個命令。最後,'nothing' 將像往常一樣僅將快照用於邏輯解碼,但不會對其執行任何其他操作。

FAILOVER [ boolean ]

如果為 true,則啟用該槽以同步到備用伺服器,以便在故障轉移後可以恢復邏輯複製。預設為 false。

響應此命令,伺服器將傳送一個單行結果集,包含以下欄位:

slot_name (text)

新建立的複製槽的名稱。

consistent_point (text)

槽變得一致的 WAL 位置。這是在此複製槽上進行流式傳輸的最早可能的起始位置。

snapshot_name (text)

命令匯出的快照的識別符號。快照有效,直到在此連線上執行新命令或複製連線關閉。如果建立的槽是物理槽,則為 null。

output_plugin (text)

新建立的複製槽使用的輸出外掛的名稱。如果建立的槽是物理槽,則為 null。

CREATE_REPLICATION_SLOT slot_name [ TEMPORARY ] { PHYSICAL [ RESERVE_WAL ] | LOGICAL output_plugin [ EXPORT_SNAPSHOT | NOEXPORT_SNAPSHOT | USE_SNAPSHOT | TWO_PHASE ] } #

為了相容舊版本,CREATE_REPLICATION_SLOT 命令的這個備用語法仍然受支援。

ALTER_REPLICATION_SLOT slot_name ( option [, ...] ) #

更改複製槽的定義。有關複製槽的更多資訊,請參閱 26.2.6 節“複製槽”。此命令目前僅支援邏輯複製槽。

slot_name

要更改的槽的名稱。必須是有效的複製槽名稱(參見 26.2.6.1 節“查詢和操作複製槽”)。

支援以下選項:

TWO_PHASE [ boolean ]

如果為 true,此邏輯複製槽支援兩階段提交的解碼。使用此選項時,會解碼並傳輸與兩階段提交相關的命令,如 PREPARE TRANSACTIONCOMMIT PREPAREDROLLBACK PREPARED。事務將在 PREPARE TRANSACTION 時進行解碼和傳輸。

FAILOVER [ boolean ]

如果為 true,則啟用該槽以同步到備用伺服器,以便在故障轉移後可以恢復邏輯複製。

READ_REPLICATION_SLOT slot_name #

讀取與複製槽相關的一些資訊。如果複製槽不存在,則返回一個具有 NULL 值的元組。此命令目前僅支援物理複製槽。

響應此命令,伺服器將返回一個單行結果集,包含以下欄位:

slot_type (text)

複製槽的型別,為 physicalNULL

restart_lsn (text)

複製槽的 restart_lsn

restart_tli (int8)

restart_lsn 關聯的時間線 ID,遵循當前時間線歷史。

START_REPLICATION [ SLOT slot_name ] [ PHYSICAL ] XXX/XXX [ TIMELINE tli ] #

指示伺服器從 WAL 位置 XXX/XXX 開始流式傳輸 WAL。如果指定了 TIMELINE 選項,則在時間線 tli 開始流式傳輸;否則,選擇伺服器的當前時間線。伺服器可能會回覆錯誤,例如,如果請求的 WAL 部分已被回收。成功時,伺服器會響應一個 CopyBothResponse 訊息,然後開始將 WAL 流式傳輸到前端。

如果透過 slot_name 提供了槽的名稱,則在複製進行時會更新該槽,以便伺服器知道備用伺服器還需要哪些 WAL 段,以及(如果 hot_standby_feedback 開啟)哪些事務。

如果客戶端請求的時間線不是最新的,但屬於伺服器歷史的一部分,伺服器將從請求的起始點開始流式傳輸該時間線上的所有 WAL,直到伺服器切換到另一條時間線為止。如果客戶端請求在舊時間線的結束點進行流式傳輸,伺服器將完全跳過 COPY 模式。

在流式傳輸完非最新時間線上的所有 WAL 後,伺服器將透過退出 COPY 模式來結束流式傳輸。當客戶端透過也退出 COPY 模式來確認這一點後,伺服器會發送一個包含一行兩列的結果集,指示此伺服器歷史中的下一個時間線。第一列是下一個時間線的 ID(型別 int8),第二列是發生切換的 WAL 位置(型別 text)。通常,切換位置是流式傳輸的 WAL 的結束位置,但也有特殊情況,伺服器可能會發送一些它自己尚未重放的舊時間線的 WAL,然後再提升。

WAL 資料作為一系列 CopyData 訊息傳送;有關詳細資訊,請參閱 54.6 節“訊息資料型別”54.7 節“訊息格式”。(這允許混合其他資訊;特別是,伺服器可以在開始流式傳輸後傳送一個 ErrorResponse 訊息,如果遇到失敗。)從伺服器到客戶端的每個 CopyData 訊息的有效負載都包含以下格式之一的訊息:

XLogData (B) #
Byte1('w')

標識訊息為 WAL 資料。

Int64

此訊息中 WAL 資料的起始點。

Int64

伺服器上的當前 WAL 結束位置。

Int64

伺服器的系統時鐘在傳輸時的值,表示自 2000-01-01 午夜以來的微秒數。

Byten

WAL 資料流的一部分。

單個 WAL 記錄永遠不會跨越兩個 XLogData 訊息。當 WAL 記錄跨越 WAL 頁面邊界,因此已使用連續記錄進行分割時,可以在頁面邊界處進行分割。換句話說,第一個主要 WAL 記錄及其連續記錄可以傳送在不同的 XLogData 訊息中。

Primary keepalive message (B) #
Byte1('k')

標識訊息為傳送方 keepalive。

Int64

伺服器上的當前 WAL 結束位置。

Int64

伺服器的系統時鐘在傳輸時的值,表示自 2000-01-01 午夜以來的微秒數。

Byte1

1 表示客戶端應儘快回覆此訊息,以避免超時斷開連線。否則為 0。

接收程序可以隨時使用以下訊息格式之一(也在 CopyData 訊息的有效負載中)將回復發送回傳送方:

Standby status update (F) #
Byte1('r')

標識訊息為接收方狀態更新。

Int64

在備用伺服器上接收並寫入磁碟的最後一個 WAL 位元組 + 1 的位置。

Int64

在備用伺服器上重新整理到磁碟的最後一個 WAL 位元組 + 1 的位置。

Int64

在備用伺服器上應用(applied)的最後一個 WAL 位元組 + 1 的位置。

Int64

客戶端系統時鐘在傳輸時的值,表示自 2000-01-01 午夜以來的微秒數。

Byte1

如果為 1,客戶端請求伺服器立即回覆此訊息。這可以用來 ping 伺服器,以測試連線是否仍然健康。

Hot standby feedback message (F) #
Byte1('h')

標識訊息為熱備用反饋訊息。

Int64

客戶端系統時鐘在傳輸時的值,表示自 2000-01-01 午夜以來的微秒數。

Int32

備用伺服器的當前全域性 xmin,不包括任何複製槽的 catalog_xmin。如果此值和後面的 catalog_xmin 均為 0,則將其視為熱備用反饋將不再透過此連線傳送的通知。稍後的非零訊息可能會重新啟動反饋機制。

Int32

備用伺服器上全域性 xmin xid 的 epoch。

Int32

備用伺服器上任何複製槽的最低 catalog_xmin。如果備用伺服器上沒有 catalog_xmin 或正在停用熱備用反饋,則設定為 0。

Int32

備用伺服器上 catalog_xmin xid 的 epoch。

START_REPLICATION SLOT slot_name LOGICAL XXX/XXX [ ( option_name [ option_value ] [, ...] ) ] #

指示伺服器開始流式傳輸邏輯複製的 WAL,從 WAL 位置 XXX/XXX 或槽的 confirmed_flush_lsn(參見 53.20 節“pg_replication_slots”)開始,取兩者中較大的一個。這種行為使得客戶端更容易在沒有資料需要處理時避免更新其本地 LSN 狀態。但是,從與請求不同的 LSN 開始可能無法捕獲某些型別的客戶端錯誤;因此,客戶端在發出 START_REPLICATION 之前可能希望檢查 confirmed_flush_lsn 是否與其預期值匹配。

伺服器可能會回覆錯誤,例如,如果槽不存在。成功時,伺服器會響應一個 CopyBothResponse 訊息,然後開始將 WAL 流式傳輸到前端。

CopyBothResponse 訊息內的訊息格式與為 START_REPLICATION ... PHYSICAL 記錄的格式相同,包括兩個 CommandComplete 訊息。

所選槽關聯的輸出外掛用於處理流式傳輸的輸出。

SLOT slot_name

要從中流式傳輸更改的槽的名稱。此引數是必需的,並且必須對應一個使用 CREATE_REPLICATION_SLOTLOGICAL 模式下建立的現有邏輯複製槽。

XXX/XXX

開始流式傳輸的 WAL 位置。

option_name

傳遞給槽的邏輯解碼輸出外掛的選項的名稱。有關標準(pgoutput)外掛接受的選項,請參閱 54.5 節“邏輯流複製協議”

option_value

與指定選項關聯的可選值,形式為字串常量。

DROP_REPLICATION_SLOT slot_name [ WAIT ] #

刪除複製槽,釋放任何伺服器端預留的資源。

slot_name

要刪除的槽的名稱。

WAIT

此選項使命令在槽處於活動狀態時等待,直到其變為非活動狀態,而不是預設的引發錯誤行為。

UPLOAD_MANIFEST #

上傳備份清單,為進行增量備份做準備。

BASE_BACKUP [ ( option [, ...] ) ] #

指示伺服器開始流式傳輸基礎備份。在開始備份之前,系統會自動進入備份模式,並在備份完成後退出該模式。接受以下選項:

LABEL 'label'

設定備份的標籤。如果未指定,將使用備份標籤 base backup。標籤的引用規則與 standard_conforming_strings 開啟時的標準 SQL 字串相同。

TARGET 'target'

告訴伺服器將備份傳送到哪裡。如果目標是 client(預設值),則備份資料傳送到客戶端。如果目標是 server,則備份資料寫入伺服器,路徑由 TARGET_DETAIL 選項指定。如果目標是 blackhole,則備份資料不傳送到任何地方;它會被簡單地丟棄。

server 目標需要超級使用者許可權或被授予 pg_write_server_files 角色。

TARGET_DETAIL 'detail'

提供有關備份目標的附加資訊。

目前,此選項只能在備份目標是 server 時使用。它指定了備份應寫入的伺服器目錄。

PROGRESS [ boolean ]

如果設定為 true,則請求生成進度報告所需的資訊。這將返回每個表空間頭部的近似大小,可用於計算流的完成進度。這是透過在傳輸開始前一次性列舉所有檔案大小來計算的,因此可能會對效能產生負面影響。特別是,在傳輸第一個資料之前可能需要更長時間。由於資料庫檔案在備份過程中可能會發生變化,因此大小僅是近似值,並且可能在近似時間和實際檔案傳輸之間增長和縮小。預設為 false。

CHECKPOINT { 'fast' | 'spread' }

設定基礎備份開始時執行的檢查點型別。預設為 spread

WAL [ boolean ]

如果設定為 true,則在備份中包含必要的 WAL 段。這將在基礎目錄 tar 檔案中的 pg_wal 目錄下包含開始和停止備份之間的所有檔案。預設為 false。

WAIT [ boolean ]

如果設定為 true,備份將等待直到最後一個必需的 WAL 段被歸檔,或者在 WAL 歸檔未啟用時發出警告。如果為 false,備份既不等待也不警告,由客戶端負責確保必需的日誌可用。預設為 true。

COMPRESSION 'method'

指示伺服器使用指定的方法壓縮備份。目前支援的方法是 gziplz4zstd

COMPRESSION_DETAIL detail

為所選的壓縮方法指定詳細資訊。這隻能與 COMPRESSION 選項結合使用。如果值為整數,則表示壓縮級別。否則,它應該是逗號分隔的關鍵字列表,形式為 keywordkeyword=value。目前支援的關鍵字是 levellongworkers

level 關鍵字設定壓縮級別。對於 gzip,壓縮級別應為 1 到 9(預設 Z_DEFAULT_COMPRESSION-1)之間的整數;對於 lz4,壓縮級別應為 1 到 12 之間的整數(預設 0 表示快速壓縮模式);對於 zstd,壓縮級別應為 ZSTD_minCLevel()(通常為 -131072)和 ZSTD_maxCLevel()(通常為 22)之間的整數(預設 ZSTD_CLEVEL_DEFAULT3)。

long 關鍵字啟用長距離匹配模式,以提高壓縮率,但會增加記憶體使用。長距離模式僅支援 zstd

workers 關鍵字設定應用於並行壓縮的執行緒數。並行壓縮僅支援 zstd

MAX_RATE rate

限制(節流)伺服器到客戶端每單位時間傳輸的最大資料量。預期的單位是千位元組/秒。如果指定了此選項,則值必須為零,或者必須在 32 kB 到 1 GB(含)的範圍內。如果傳遞零或未指定此選項,則不對傳輸施加任何限制。

TABLESPACE_MAP [ boolean ]

如果為 true,則在名為 tablespace_map 的檔案中包含有關 pg_tblspc 目錄中存在的符號連結的資訊。表空間對映檔案包括 pg_tblspc/ 目錄中存在的每個符號連結名稱以及該符號連結的完整路徑。預設為 false。

VERIFY_CHECKSUMS [ boolean ]

如果為 true,則在啟用了校驗和的情況下進行基礎備份時驗證校驗和。如果為 false,則跳過此操作。預設為 true。

MANIFEST manifest_option

當此選項的值為 yesforce-encode 時,將建立備份清單並隨備份一起傳送。清單是備份中存在的所有檔案的列表,但不包括可能包含的任何 WAL 檔案。它還儲存每個檔案的大小、最後修改時間,以及可選的校驗和。值為 force-encode 會強制所有檔名進行十六進位制編碼;否則,僅對檔名是非 UTF8 位元組序列的檔案執行此類編碼。force-encode 主要用於測試目的,以確保讀取備份清單的客戶端可以處理這種情況。為了相容以前的版本,預設為 MANIFEST 'no'

MANIFEST_CHECKSUMS checksum_algorithm

指定應應用於備份清單中每個檔案的校驗和演算法。目前可用的演算法有 NONECRC32CSHA224SHA256SHA384SHA512。預設為 CRC32C

INCREMENTAL

請求增量備份。在使用此選項執行基礎備份之前,必須先執行 UPLOAD_MANIFEST 命令。

當備份開始時,伺服器將首先發送兩個普通結果集,然後是一個或多個 CopyOutResponse 結果。

第一個普通結果集包含備份的起始位置,位於一個包含兩列的單行中。第一列包含 XLogRecPtr 格式的起始位置,第二列包含相應的時間線 ID。

第二個普通結果集為每個表空間有一行。該行中的欄位是:

spcoid (oid)

表空間的 OID,如果是基目錄則為 null。

spclocation (text)

表空間目錄的完整路徑,如果是基目錄則為 null。

size (int8)

表空間的大約大小,以千位元組(1024 位元組)為單位,如果請求了進度報告;否則為 null。

在第二個常規結果集之後,將傳送一個 CopyOutResponse。每個 CopyData 訊息的有效負載將包含以下格式之一的訊息:

new archive (B)
Byte1('n')

標識訊息為新歸檔的開始。將有一個用於主資料目錄的歸檔,以及一個用於每個附加表空間的歸檔;每個都將使用 tar 格式(遵循 POSIX 1003.1-2008 標準中指定的 ustar interchange format)。

String

此歸檔的檔名。

String

對於主資料目錄,為空字串。對於其他表空間,是建立此歸檔的目錄的完整路徑。

manifest (B)
Byte1('m')

標識訊息為備份清單的開始。

archive or manifest data (B)
Byte1('d')

標識訊息包含歸檔或清單資料。

Byten

Data bytes.

progress report (B)
Byte1('p')

標識訊息為進度報告。

Int64

已處理的當前表空間的位元組數。

在所有 CopyOutResponse 傳送完畢後(或所有響應),將傳送一個最終的普通結果集,包含備份的 WAL 結束位置,格式與起始位置相同。

資料目錄和每個表空間的 tar 歸檔將包含目錄中的所有檔案,無論它們是 PostgreSQL 檔案還是新增到同一目錄的其他檔案。唯一排除的檔案是:

  • postmaster.pid

  • postmaster.opts

  • pg_internal.init(在多個目錄中找到)

  • PostgreSQL 伺服器執行期間建立的各種臨時檔案和目錄,例如以 pgsql_tmp 開頭的任何檔案或目錄,以及臨時關係。

  • 未記錄的關係,除了用於在恢復時重新建立(空)未記錄關係的 init fork。

  • pg_wal,包括子目錄。如果備份執行時包含 WAL 檔案,則會包含一個合成的 pg_wal 版本,但它將只包含備份正常工作所需的檔案,而不是其其餘內容。

  • pg_dynshmempg_notifypg_replslotpg_serialpg_snapshotspg_stat_tmppg_subtrans 將作為空目錄複製(即使它們是符號連結)。

  • 常規檔案和目錄以外的檔案,例如符號連結(上面列出的目錄除外)和特殊裝置和作業系統檔案,將被跳過。(pg_tblspc 中的符號連結會被保留。)

如果伺服器上的底層檔案系統支援,將設定所有者、組和檔案模式。

在上述所有命令中,當指定布林型別 (boolean) 的引數時,可以省略 value 部分,這等同於指定 TRUE

提交更正

如果您在文件中看到任何不正確、與您對特定功能的體驗不符或需要進一步澄清的內容,請使用 此表單 報告文件問題。