支援的版本: 目前 (17) / 16 / 15 / 14 / 13
開發版本: devel
不支援的版本: 12 / 11 / 10 / 9.6 / 9.5 / 9.4 / 9.3

F.36. postgres_fdw — 存取儲存在外部 PostgreSQL 伺服器上的資料 #

postgres_fdw 模組提供了外部資料包裝器 postgres_fdw,可用於存取儲存在外部 PostgreSQL 伺服器上的資料。

此模組提供的功能與較舊的 dblink 模組的功能有很大的重疊。但是 postgres_fdw 提供了更透明且符合標準的語法來存取遠端表格,並且在許多情況下可以提供更好的效能。

要準備使用 postgres_fdw 進行遠端存取:

  1. 使用 CREATE EXTENSION 安裝 postgres_fdw 擴充功能。

  2. 使用 CREATE SERVER 建立外部伺服器物件,以表示您要連線的每個遠端資料庫。 指定連線資訊 (除了 userpassword),作為伺服器物件的選項。

  3. 使用 CREATE USER MAPPING,為您要允許存取每個外部伺服器的每個資料庫使用者建立使用者對應。將要使用的遠端使用者名稱和密碼指定為使用者對應的 userpassword 選項。

  4. 使用 CREATE FOREIGN TABLEIMPORT FOREIGN SCHEMA,為您要存取的每個遠端表格建立外部表格。外部表格的欄位必須與參考的遠端表格相符。但是,如果將正確的遠端名稱指定為外部表格物件的選項,則可以使用與遠端表格不同的表格和/或欄位名稱。

現在,您只需要從外部表格 SELECT 即可存取儲存在其底層遠端表格中的資料。您也可以使用 INSERTUPDATEDELETECOPYTRUNCATE 修改遠端表格。(當然,您在使用者對應中指定的遠端使用者必須具有執行這些操作的權限。)

請注意,在存取或修改遠端表格時,SELECTUPDATEDELETETRUNCATE 中指定的 ONLY 選項無效。

請注意,postgres_fdw 目前不支援帶有 ON CONFLICT DO UPDATE 子句的 INSERT 陳述式。但是,如果省略唯一索引推斷規格,則支援 ON CONFLICT DO NOTHING 子句。另請注意,postgres_fdw 支援由對分割表格執行的 UPDATE 陳述式所調用的列移動,但目前不處理選擇將移動的列插入到的遠端分割區也是 UPDATE 目標分割區的情況,該分割區將在同一命令中的其他位置更新。

通常建議使用與遠端表格的參考欄位完全相同的資料類型(如果適用,則使用定序)來宣告外部表格的欄位。儘管 postgres_fdw 目前相當寬容地根據需要在執行資料類型轉換,但由於遠端伺服器以與本機伺服器不同的方式解釋查詢條件,因此當類型或定序不符時,可能會出現令人驚訝的語意異常。

請注意,宣告的外部表格可以比其底層遠端表格具有更少的欄位,或者具有不同的欄位順序。欄位與遠端表格的對應是按名稱而不是位置進行的。

F.36.1. postgres_fdw 的 FDW 選項 #

F.36.1.1. 連線選項 #

使用 postgres_fdw 外部資料包裝器的外部伺服器可以具有 libpq 在連線字串中接受的相同選項,如 第 32.1.2 節 中所述,但以下選項不允許或具有特殊處理:

  • userpasswordsslpassword (請在使用者對應中指定這些,或使用服務檔案)

  • client_encoding (這是從本機伺服器編碼自動設定的)

  • application_name - 這個設定可能出現在連線設定和 postgres_fdw.application_name 其中一個或兩個都出現。如果兩者都存在,postgres_fdw.application_name 會覆蓋連線設定。與 libpq 不同,postgres_fdw 允許 application_name 包含跳脫序列。詳情請參閱 postgres_fdw.application_name

  • fallback_application_name (總是設定為 postgres_fdw)

  • sslkeysslcert - 這些設定可能出現在連線設定和使用者對應 其中一個或兩個都出現。如果兩者都存在,使用者對應設定會覆蓋連線設定。

只有超級使用者才能建立或修改包含 sslcertsslkey 設定的使用者對應。

非超級使用者可以使用密碼驗證或 GSSAPI 委派憑證連線到外部伺服器,因此,如果需要密碼驗證,請為屬於非超級使用者的使用者對應指定 password 選項。

超級使用者可以通過設定使用者對應選項 password_required 'false',來覆蓋每個使用者對應的此檢查,例如:

ALTER USER MAPPING FOR some_non_superuser SERVER loopback_nopw
OPTIONS (ADD password_required 'false');

為了防止非特權使用者利用 postgres 伺服器執行的 unix 使用者的驗證權限來提升為超級使用者權限,只有超級使用者才能在使用者對應上設定此選項。

需要小心謹慎,以確保這不會允許映射使用者以超級使用者身份連線到每個 CVE-2007-3278 和 CVE-2007-6601 的映射資料庫。不要在 public 角色上設定 password_required=false。請記住,映射使用者可能會使用 postgres 伺服器執行的系統使用者的 unix 主目錄中的任何客戶端憑證、.pgpass.pg_service.conf 等。他們也可以使用身份驗證模式(如 peerident 身份驗證)授予的任何信任關係。

F.36.1.2. 物件名稱選項 #

這些選項可用於控制發送到遠端 PostgreSQL 伺服器的 SQL 陳述式中使用的名稱。當使用與底層遠端表名稱不同的名稱建立外部表時,需要這些選項。

schema_name (string)

此選項可以為外部表指定,提供要在遠端伺服器上用於外部表的綱要名稱。如果省略此選項,則使用外部表的綱要名稱。

table_name (string)

此選項可以為外部表指定,提供要在遠端伺服器上用於外部表的表名稱。如果省略此選項,則使用外部表的名稱。

column_name (string)

此選項可以為外部表的欄位指定,提供要在遠端伺服器上用於欄位的欄位名稱。如果省略此選項,則使用欄位的名稱。

F.36.1.3. 成本估算選項 #

postgres_fdw 通過對遠端伺服器執行查詢來檢索遠端資料,因此理想情況下,掃描外部表的估計成本應該是遠端伺服器上的執行成本,加上一些通訊開銷。獲得此類估計的最可靠方法是詢問遠端伺服器,然後添加一些開銷 - 但對於簡單的查詢,額外進行一次遠端查詢來獲得成本估算可能並不值得。因此,postgres_fdw 提供了以下選項來控制成本估算的執行方式

use_remote_estimate (boolean)

此選項可以為外部表或外部伺服器指定,控制 postgres_fdw 是否發出遠端 EXPLAIN 命令來獲取成本估算。外部表的設定會覆蓋其伺服器的任何設定,但僅適用於該表。預設值為 false

fdw_startup_cost (floating point)

此選項可以為外部伺服器指定,是一個浮點數值,會被加到該伺服器上任何外部表掃描的估計啟動成本中。這表示建立連線、在遠端解析和規劃查詢等額外開銷。預設值為 100

fdw_tuple_cost (floating point)

此選項可以為外部伺服器指定,是一個浮點數值,用作該伺服器上外部表掃描的每個元組的額外成本。這表示伺服器之間資料傳輸的額外開銷。您可以增加或減少這個數字,以反映到遠端伺服器的網路延遲是較高還是較低。預設值為 0.2

use_remote_estimate 為 true 時,postgres_fdw 從遠端伺服器獲取行數和成本估算,然後將 fdw_startup_costfdw_tuple_cost 添加到成本估算中。當 use_remote_estimate 為 false 時,postgres_fdw 執行本地行數和成本估算,然後將 fdw_startup_costfdw_tuple_cost 添加到成本估算中。除非遠端表的統計資訊有本地副本,否則此本地估算不太準確。在外部表上執行 ANALYZE 是更新本地統計資訊的方法;這將執行遠端表的掃描,然後計算並儲存統計資訊,就像表是本地表一樣。保留本地統計資訊是減少遠端表每次查詢規劃開銷的有用方法 - 但如果遠端表經常更新,本地統計資訊很快就會過時。

以下選項控制此類 ANALYZE 操作的行為

analyze_sampling (string)

此選項可以為外部表或外部伺服器指定,決定在外部表上執行 ANALYZE 時,是在遠端對資料進行取樣,還是讀取並傳輸所有資料並在本地執行取樣。支援的值為 offrandomsystembernoulliautooff 禁用遠端取樣,因此所有資料都會被傳輸並在本地取樣。random 使用 random() 函數執行遠端取樣以選擇傳回的列,而 systembernoulli 依賴於這些名稱的內建 TABLESAMPLE 方法。random 適用於所有遠端伺服器版本,而 TABLESAMPLE 僅自 9.5 起支援。auto (預設值) 自動選擇建議的取樣方法;目前這意味著 bernoullirandom,具體取決於遠端伺服器版本。

F.36.1.4. 遠端執行選項 #

預設情況下,只有使用內建運算符和函數的 WHERE 子句會被考慮在遠端伺服器上執行。涉及非內建函數的子句會在提取列之後在本地進行檢查。如果這些函數在遠端伺服器上可用,並且可以依賴它們產生與本地相同結果,則可以通過傳送此類 WHERE 子句以進行遠端執行來提高效能。可以使用以下選項控制此行為

extensions (string)

這個選項是一個以逗號分隔的 PostgreSQL 擴充套件名稱清單,這些擴充套件以相容的版本安裝在本機和遠端伺服器上。 屬於已列出擴充套件且為不可變的函式和運算子將被視為可傳送到遠端伺服器。 這個選項只能為外部伺服器指定,不能針對單獨的表格指定。

當使用 extensions 選項時,使用者有責任確保列出的擴充套件在本機和遠端伺服器上都存在且行為相同。 否則,遠端查詢可能會失敗或行為異常。

fetch_size (integer)

這個選項指定了 postgres_fdw 在每次提取操作中應該獲取的行數。 它可以為外部表格或外部伺服器指定。 在表格上指定的選項會覆蓋在伺服器上指定的選項。 預設值為 100

batch_size (integer)

這個選項指定了 postgres_fdw 在每次插入操作中應該插入的行數。 它可以為外部表格或外部伺服器指定。 在表格上指定的選項會覆蓋在伺服器上指定的選項。 預設值為 1

請注意,postgres_fdw 實際一次插入的行數取決於欄位數和提供的 batch_size 值。 該批次會作為單一查詢執行,並且 libpq 協定 ( postgres_fdw 用於連接遠端伺服器) 將單一查詢中的參數數量限制為 65535。 當欄位數 * batch_size 超過限制時,batch_size 將會被調整以避免錯誤。

這個選項也適用於複製到外部表格的情況。 在這種情況下,postgres_fdw 一次複製的實際行數的確定方式與插入情況類似,但由於 COPY 命令的實作限制,最多限制為 1000。

F.36.1.5. 非同步執行選項 #

postgres_fdw 支援非同步執行,它並行而非依序執行 Append 節點的多個部分,以提高效能。 可以使用以下選項來控制此執行方式

async_capable (boolean)

這個選項控制 postgres_fdw 是否允許並行掃描外部表格以進行非同步執行。 它可以為外部表格或外部伺服器指定。 表格層級的選項會覆蓋伺服器層級的選項。 預設值為 false

為了確保從外部伺服器傳回的資料一致,postgres_fdw 將只為給定的外部伺服器開啟一個連線,並且會依序執行針對該伺服器的所有查詢,即使涉及多個外部表格,除非這些表格受限於不同的使用者映射。 在這種情況下,停用此選項以消除與非同步執行查詢相關聯的額外負荷可能更有效。

即使 Append 節點包含同步執行的子計畫和非同步執行的子計畫,也會應用非同步執行。 在這種情況下,如果非同步子計畫是使用 postgres_fdw 處理的,則在至少一個同步子計畫傳回所有元組之後,才會傳回來自非同步子計畫的元組,因為該子計畫在非同步子計畫等待傳送到外部伺服器的非同步查詢結果時執行。 此行為可能會在未來的版本中更改。

F.36.1.6. 交易管理選項 #

如交易管理章節中所述,在 postgres_fdw 中,交易透過建立相應的遠端交易來管理,而子交易則透過建立相應的遠端子交易來管理。 當多個遠端交易參與目前的本機交易時,預設情況下,當本機交易提交或中止時,postgres_fdw 會依序提交或中止這些遠端交易。 當多個遠端子交易參與目前的本機子交易時,預設情況下,當本機子交易提交或中止時,postgres_fdw 會依序提交或中止這些遠端子交易。 可以使用以下選項來提高效能

parallel_commit (boolean)

這個選項控制當本機交易提交時,postgres_fdw 是否並行提交在本機交易中於外部伺服器上開啟的遠端交易。 這個設定也適用於遠端和本機子交易。 這個選項只能為外部伺服器指定,不能針對單獨的表格指定。 預設值為 false

parallel_abort (boolean)

這個選項控制當本機交易中止時,postgres_fdw 是否並行中止在本機交易中於外部伺服器上開啟的遠端交易。 這個設定也適用於遠端和本機子交易。 這個選項只能為外部伺服器指定,不能針對單獨的表格指定。 預設值為 false

如果多個啟用了這些選項的外部伺服器參與本機交易,則當本機交易提交或中止時,將在這些外部伺服器上並行提交或中止多個遠端交易。

當啟用這些選項時,具有許多遠端交易的外部伺服器在本機交易提交或中止時可能會看到負面的效能影響。

F.36.1.7. 可更新性選項 #

預設情況下,所有使用 postgres_fdw 的外部表格都被假定為可更新。 可以使用以下選項來覆蓋此設定

updatable (boolean)

這個選項控制 postgres_fdw 是否允許使用 INSERTUPDATEDELETE 命令修改外部表格。 它可以為外部表格或外部伺服器指定。 表格層級的選項會覆蓋伺服器層級的選項。 預設值為 true

當然,如果遠端表格實際上不可更新,無論如何都會發生錯誤。 使用此選項主要允許在不查詢遠端伺服器的情況下在本機擲出錯誤。 但是請注意,information_schema 檢視表會根據此選項的設定報告 postgres_fdw 外部表格是否可更新,而不會檢查遠端伺服器。

F.36.1.8. 可截斷性選項 #

預設情況下,所有使用 postgres_fdw 的外部表格都被假定為可截斷。 可以使用以下選項來覆蓋此設定

truncatable (boolean)

這個選項控制 postgres_fdw 是否允許使用 TRUNCATE 命令截斷外部表格。 它可以為外部表格或外部伺服器指定。 表格層級的選項會覆蓋伺服器層級的選項。 預設值為 true

當然,如果遠端表格實際上不可截斷,無論如何都會發生錯誤。 使用此選項主要允許在不查詢遠端伺服器的情況下在本機擲出錯誤。

F.36.1.9. 匯入選項 #

postgres_fdw 能夠使用 IMPORT FOREIGN SCHEMA 匯入外部表格定義。 這個命令在本機伺服器上建立與遠端伺服器上存在的表格或檢視表相符的外部表格定義。 如果要匯入的遠端表格具有使用者定義資料類型的欄位,則本機伺服器必須具有相容的同名類型。

可以使用以下選項 (在 IMPORT FOREIGN SCHEMA 命令中給出) 自訂匯入行為

import_collate (boolean)

這個選項控制是否將欄位的 COLLATE 選項包含在從外部伺服器匯入的外部表格定義中。預設值為 true。如果遠端伺服器的排序規則名稱與本地伺服器不同,您可能需要關閉此選項,如果遠端伺服器在不同的作業系統上執行,則很可能發生這種情況。但是,如果這樣做,匯入的表格欄位的排序規則很可能與底層資料不符,從而導致異常的查詢行為。

即使將此參數設定為 true,匯入排序規則為遠端伺服器預設值的欄位也可能存在風險。它們將以 COLLATE "default" 匯入,這將選擇本地伺服器的預設排序規則,而該排序規則可能不同。

import_default (boolean)

這個選項控制是否將欄位的 DEFAULT 表達式包含在從外部伺服器匯入的外部表格定義中。預設值為 false。如果啟用此選項,請注意在本地伺服器上的計算方式可能與在遠端伺服器上不同的預設值;nextval() 是一個常見的問題來源。如果匯入的預設表達式使用本地不存在的函式或運算子,則 IMPORT 將完全失敗。

import_generated (boolean)

這個選項控制是否將欄位的 GENERATED 表達式包含在從外部伺服器匯入的外部表格定義中。預設值為 true。如果匯入的產生表達式使用本地不存在的函式或運算子,則 IMPORT 將完全失敗。

import_not_null (boolean)

這個選項控制是否將欄位的 NOT NULL 約束包含在從外部伺服器匯入的外部表格定義中。預設值為 true

請注意,除了 NOT NULL 之外的約束永遠不會從遠端表格匯入。儘管 PostgreSQL 確實支援外部表格上的檢查約束,但沒有自動匯入它們的規定,因為約束表達式在本地和遠端伺服器上的評估結果可能不同。檢查約束行為中的任何此類不一致都可能導致查詢最佳化中難以偵測到的錯誤。因此,如果您希望匯入檢查約束,則必須手動執行,並且應仔細驗證每個約束的語義。有關外部表格上檢查約束處理的更多詳細資訊,請參閱 CREATE FOREIGN TABLE

僅當在 LIMIT TO 子句中明確指定時,才會匯入作為其他表格分割區的表格或外部表格。否則,它們會自動從 IMPORT FOREIGN SCHEMA 中排除。由於所有資料都可以通過作為分割階層根的分割表格訪問,因此僅匯入分割表格應允許訪問所有資料,而無需建立額外的物件。

F.36.1.10. 連線管理選項 #

預設情況下,postgres_fdw 建立到外部伺服器的所有連線都會在本地會話中保持開啟以供重複使用。

keep_connections (boolean)

這個選項控制 postgres_fdw 是否保持與外部伺服器的連線開啟,以便後續查詢可以重複使用它們。它只能為外部伺服器指定。預設值為 on。如果設定為 off,則在每個交易結束時將丟棄與此外部伺服器的所有連線。

F.36.2. 函式 #

postgres_fdw_get_connections(OUT server_name text, OUT valid boolean) returns setof record

這個函式會傳回所有 postgres_fdw 從本地會話建立到外部伺服器的開啟連線的外部伺服器名稱。它還傳回每個連線是否有效。false 會在下列情況傳回:外部伺服器連線用於目前的本地交易,但其外部伺服器或使用者對應已變更或卸除(請注意,如果伺服器已卸除,則無效連線的伺服器名稱將為 NULL),然後此類無效連線將在該交易結束時關閉。true 會在其他情況下傳回。如果沒有開啟的連線,則不會傳回任何記錄。函式的使用範例

postgres=# SELECT * FROM postgres_fdw_get_connections() ORDER BY 1;
 server_name | valid
-------------+-------
 loopback1   | t
 loopback2   | f
postgres_fdw_disconnect(server_name text) returns boolean

這個函式會丟棄 postgres_fdw 從本地會話建立到具有指定名稱的外部伺服器的開啟連線。請注意,可以使用不同的使用者對應連線到給定的伺服器。如果這些連線用於目前的本地交易,則它們不會斷線,並且會報告警告訊息。如果斷線至少一個連線,則此函式會傳回 true,否則傳回 false。如果找不到具有指定名稱的外部伺服器,則會報告錯誤。函式的使用範例

postgres=# SELECT postgres_fdw_disconnect('loopback1');
 postgres_fdw_disconnect
-------------------------
 t
postgres_fdw_disconnect_all() returns boolean

這個函式會丟棄所有 postgres_fdw 從本地會話建立到外部伺服器的開啟連線。如果這些連線用於目前的本地交易,則它們不會斷線,並且會報告警告訊息。如果斷線至少一個連線,則此函式會傳回 true,否則傳回 false。函式的使用範例

postgres=# SELECT postgres_fdw_disconnect_all();
 postgres_fdw_disconnect_all
-----------------------------
 t

F.36.3. 連線管理 #

postgres_fdw 在第一次使用與外部伺服器關聯的外部表格的查詢期間,會建立與外部伺服器的連線。預設情況下,此連線會保留並重複用於同一會話中的後續查詢。可以使用外部伺服器的 keep_connections 選項控制此行為。如果使用多個使用者身分(使用者對應)來訪問外部伺服器,則會為每個使用者對應建立一個連線。

變更外部伺服器或使用者對應的定義或移除它們時,會關閉相關聯的連線。但是請注意,如果在目前的本地交易中使用任何連線,則會將它們保留到交易結束為止。當將來使用外部表格的查詢需要時,將重新建立已關閉的連線。

一旦建立了與外部伺服器的連線,預設情況下,它會一直保留到本地或相應的遠端會話結束為止。要明確斷開連線,可以停用外部伺服器的 keep_connections 選項,或者可以使用 postgres_fdw_disconnectpostgres_fdw_disconnect_all 函式。例如,這些對於關閉不再需要的連線非常有用,從而釋放外部伺服器上的連線。

F.36.4. 交易管理 #

在查詢中引用外部伺服器上的任何遠端資料表時,如果目前本機交易尚未開啟對應的遠端伺服器交易,postgres_fdw 會在遠端伺服器上開啟一個交易。當本機交易提交或中止時,遠端交易也會提交或中止。儲存點也透過建立對應的遠端儲存點來進行管理。

當本機交易具有 SERIALIZABLE 隔離等級時,遠端交易使用 SERIALIZABLE 隔離等級;否則,它使用 REPEATABLE READ 隔離等級。這種選擇確保了如果查詢在遠端伺服器上執行多次資料表掃描,它將獲得所有掃描的一致性快照結果。一個後果是,單一交易中的後續查詢將看到來自遠端伺服器的相同資料,即使由於其他活動而導致遠端伺服器上發生並行更新。如果本機交易使用 SERIALIZABLEREPEATABLE READ 隔離等級,則無論如何都會預期這種行為,但對於 READ COMMITTED 本機交易來說,這可能會令人驚訝。未來的 PostgreSQL 版本可能會修改這些規則。

請注意,目前 postgres_fdw 不支援準備遠端交易以進行兩階段提交。

F.36.5. 遠端查詢最佳化 #

postgres_fdw 嘗試最佳化遠端查詢,以減少從外部伺服器傳輸的資料量。這是透過將查詢 WHERE 子句傳送到遠端伺服器執行,以及不檢索目前查詢不需要的資料表欄位來完成的。為了降低查詢錯誤執行的風險,除非 WHERE 子句僅使用內建的資料類型、運算子和函式,或者屬於外部伺服器 extensions 選項中列出的擴充功能,否則不會將這些子句傳送到遠端伺服器。這些子句中的運算子和函式也必須是 IMMUTABLE。對於 UPDATEDELETE 查詢,如果沒有無法傳送到遠端伺服器的查詢 WHERE 子句、查詢沒有本機聯結、目標資料表上沒有列層級的本機 BEFOREAFTER 觸發程序或儲存的產生欄位,以及沒有來自父視窗的 CHECK OPTION 限制,postgres_fdw 會嘗試將整個查詢傳送到遠端伺服器來最佳化查詢執行。在 UPDATE 中,賦予目標欄位的運算式必須僅使用內建資料類型、IMMUTABLE 運算子或 IMMUTABLE 函式,以降低查詢錯誤執行的風險。

postgres_fdw 遇到在同一外部伺服器上的外部資料表之間的聯結時,它會將整個聯結傳送到外部伺服器,除非由於某種原因它認為從每個資料表個別提取列會更有效率,或者涉及的資料表參考受到不同的使用者對應的約束。在傳送 JOIN 子句時,它會採取與上述 WHERE 子句相同的預防措施。

可以使用 EXPLAIN VERBOSE 檢查實際傳送到遠端伺服器執行的查詢。

F.36.6. 遠端查詢執行環境 #

postgres_fdw 開啟的遠端連線中,search_path 參數僅設定為 pg_catalog,因此只有內建物件在沒有綱要限定的情況下可見。對於 postgres_fdw 本身產生的查詢,這不是問題,因為它總是提供這種限定。但是,這對於透過遠端資料表上的觸發程序或規則在遠端伺服器上執行的函式可能會造成危險。例如,如果遠端資料表實際上是一個視窗,則在該視窗中使用的任何函式都將以受限的搜尋路徑執行。建議對這些函式中的所有名稱進行綱要限定,或者將 SET search_path 選項(請參閱 CREATE FUNCTION)附加到這些函式,以建立其預期的搜尋路徑環境。

postgres_fdw 也為各種參數建立遠端連線設定

這些問題發生的可能性不如 search_path 那麼大,但如果需要,可以使用函式 SET 選項來處理。

強烈建議您透過變更這些參數的連線層級設定來覆寫此行為;這可能會導致 postgres_fdw 發生故障。

F.36.7. 跨版本相容性 #

postgres_fdw 可與追溯到 PostgreSQL 8.3 的遠端伺服器一起使用。回溯到 8.1,可提供唯讀功能。但是,一個限制是,如果 WHERE 子句中出現了外部資料表,postgres_fdw 通常會假設不可變的內建函式和運算子可以安全地傳送到遠端伺服器執行。因此,自遠端伺服器發佈以來新增的內建函式可能會傳送到遠端伺服器執行,從而導致 function does not exist 或類似錯誤。可以透過重寫查詢來解決此類故障,例如,透過將外部資料表參考嵌入到具有 OFFSET 0 的子-SELECT 中作為最佳化圍欄,並將有問題的函式或運算子放置在子-SELECT 之外。

F.36.8. 等待事件 #

postgres_fdw 可以在等待事件類型 Extension 下報告以下等待事件

PostgresFdwCleanupResult

等待遠端伺服器上的交易中止。

PostgresFdwConnect

等待建立與遠端伺服器的連線。

PostgresFdwGetResult

等待接收來自遠端伺服器的查詢結果。

F.36.9. 組態參數 #

postgres_fdw.application_name (string) #

指定當 postgres_fdw 建立與外部伺服器的連線時,所使用的 application_name 設定參數的值。這會覆寫伺服器物件的 application_name 選項。請注意,變更此參數不會影響任何現有連線,直到它們重新建立。

postgres_fdw.application_name 可以是任何長度的字串,甚至可以包含非 ASCII 字元。但是,當它傳遞到外部伺服器並用作其中的 application_name 時,請注意它將被截斷為小於 NAMEDATALEN 個字元。除了可列印的 ASCII 字元之外的任何字元都會被替換為 C 樣式十六進位跳脫字元。有關詳細資訊,請參閱 application_name

% 字元開始 跳脫序列,這些序列會被替換為如下所述的狀態資訊。無法識別的跳脫序列會被忽略。其他字元會直接複製到應用程式名稱中。請注意,不允許在 % 之後和選項之前指定加號/減號或數值常值,以進行對齊和填充。

跳脫字元 效果
%a 本機伺服器上的應用程式名稱
%c 本機伺服器上的 Session ID(請參閱 log_line_prefix 以了解詳細資訊)
%C 本機伺服器上的叢集名稱(請參閱 cluster_name 以了解詳細資訊)
%u 本機伺服器上的使用者名稱
%d 本機伺服器上的資料庫名稱
%p 本機伺服器上後端處理序的處理序 ID
%% Literal %

例如,假設使用者 local_user 從資料庫 local_db 建立與 foreign_db 的連線,並使用使用者 foreign_user 身份,則設定 'db=%d, user=%u' 會被替換為 'db=local_db, user=local_user'

F.36.10. 範例 #

以下是使用 postgres_fdw 建立外部表格的範例。首先安裝擴充功能

CREATE EXTENSION postgres_fdw;

然後使用 CREATE SERVER 建立外部伺服器。在此範例中,我們希望連線到主機 192.83.123.89 上監聽埠 5432PostgreSQL 伺服器。要連線的資料庫在遠端伺服器上名為 foreign_db

CREATE SERVER foreign_server
        FOREIGN DATA WRAPPER postgres_fdw
        OPTIONS (host '192.83.123.89', port '5432', dbname 'foreign_db');

還需要使用 CREATE USER MAPPING 定義使用者對應,以識別將在遠端伺服器上使用的角色

CREATE USER MAPPING FOR local_user
        SERVER foreign_server
        OPTIONS (user 'foreign_user', password 'password');

現在可以使用 CREATE FOREIGN TABLE 建立外部表格。在此範例中,我們希望存取遠端伺服器上名為 some_schema.some_table 的表格。它的本機名稱將為 foreign_table

CREATE FOREIGN TABLE foreign_table (
        id integer NOT NULL,
        data text
)
        SERVER foreign_server
        OPTIONS (schema_name 'some_schema', table_name 'some_table');

至關重要的是,在 CREATE FOREIGN TABLE 中宣告的欄位的資料類型和其他屬性與實際的遠端表格相符。欄位名稱也必須匹配,除非您將 column_name 選項附加到各個欄位,以顯示它們在遠端表格中的命名方式。在許多情況下,使用 IMPORT FOREIGN SCHEMA 比手動建構外部表格定義更好。

F.36.11. 作者 #

Shigeru Hanada

提交更正

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