一、FDW簡介
FDW 是 PostgreSQL 提供的一個特性,它能夠讓用戶在 PostgreSQL 中創建 外部表(Foreign Table)。外部表將被作為代理,用于訪問外部數據源。當用戶對外部表發起查詢時,FDW 會負責把查詢進行一定的形式轉換后訪問外部數據源,并負責將外部數據源返回的數據轉換回 PostgreSQL 的結果形式,讓用戶覺得查詢一個外部數據源好像和查詢一個數據庫內的普通表一樣沒什么區別。
目前 PostgreSQL 官方提供了兩個 FDW 實現:
file_fdw:使用戶能夠創建代表普通文件的外部表postgres_fdw:使用戶能夠創建代表另一個 PostgreSQL 數據庫表的外部表
二、問題概述
在一個客戶在使用postgres_fdw 外部表進行查詢數據時,發現在數據量比較大的情況下執行的時間非常的長甚至已經到不可用的狀態。
2.1 排查網絡
排查本地pg到外部服務器之間的網絡配置及網絡流量,本地網絡帶寬6Gbps,流量最大4MB/s;
說明網絡帶寬及網絡流量遠遠沒有達到上限,但是流量為什么只有4MB/s呢,查詢的數據量非常大按照道理來說流量已經會有一個比較高的峰值才對?
2.2 檢查數據庫配置
檢查數據庫的參數,本地及遠程服務器內存配置較大;并發參數設置也合理。
2.3 測試查詢
1. 在本地客戶端執行查詢,使用limit 進行不同數據量的外表查詢,在limit比較少時查詢非常快,但limit越大,發現執行時間越久。
2. 客戶端連接遠程服務器,使用sql測試執行比較快;說明遠程數據庫也非執行較慢的瓶頸。
2.4 查看外部表配置
查看外部表配置,只有基本的數據庫信息配置,沒有設置任何的參數。從前面的排查過程看,定位在本地執行外部表交互上,但網絡帶寬及網絡流量看都未觸及瓶頸。
根據外部表配置參數,fetch_size postgres_fdw在每次獲取操作中應獲取的行數,默認值為100。也就是默認配置下外部表每次執行獲取100行,在大數據量的情況下會產生非常多小數據量的傳輸交互,所以這里也說明了為什么查看網絡流量時,最大的流量很小。
fetch_size(integer)fetch_size(integer)This option specifies the number of rows
postgres_fdwshould get in each fetch operation. It can be specified for a foreign table or a foreign server. The option specified on a table overrides an option specified for the server. The default is100.
三、問題原因
在配置postgres_fdw時,未配置參數導致執行產生了非常多的小數據量的傳輸交互,導致了大量的時間消耗。
四、解決方案
配置postgres_fdw 配置外部服務器的fetch_size,如果版本在14之后可以開啟異步同步。
具體fetch_size配置值可以測試不同配置的執行時間。
ALTER SERVER foreign_server
OPTIONS (ADD async_capable 'true',ADD fetch_size '50000');客戶fetch_size 配置100000后原需要4個多小時都無法執行出的sql,修改后10分鐘可以執行完成,執行時間大幅提升。




