阿里云支持通過oss_fdw插件將OSS中的數據加載到RDS PostgreSQL數據庫中,也支持將RDS PostgreSQL數據庫中的數據寫入OSS中。
前提條件
RDS PostgreSQL實例大版本為10或以上。
如果實例版本為PostgreSQL 14,需要內核小版本大于等于20220830。如需升級內核小版本,請參見升級內核小版本。
oss_fdw用例
創建oss_fdw插件。詳細參數請參見oss_fdw參數。
CREATE EXTENSION oss_fdw;
創建SERVER。詳細參數請參見CREATE SERVER參數。
CREATE SERVER ossserver FOREIGN DATA WRAPPER oss_fdw OPTIONS (host 'oss-cn-hangzhou-internal.aliyuncs.com' , id 'access_id', key 'secrect_key',bucket 'mybucket');
創建OSS外部表。詳細參數請參見CREATE FOREIGN TABLE參數。
CREATE FOREIGN TABLE ossexample (date text, time text, open float, high float, low float, volume int) SERVER ossserver OPTIONS ( dir 'osstest/', delimiter ',' , format 'csv', encoding 'utf8');
重要建表語句中的表結構僅為示例,實際情況下,外部表的結構須與OSS文件對應的表結構保持一致。
讀、寫OSS中的數據。
讀取OSS中的數據。
SELECT * FROM ossexample;
將OSS中的數據插入到RDS PostgreSQL實例中。
創建與外部表ossexample結構相同的表example。
CREATE TABLE example (date text, time text, open float, high float, low float, volume int);
將OSS中的數據插入到表example中。
INSERT INTO example SELECT * FROM ossexample;
您可以通過
EXPLAIN
估算OSS上的文件大小,正確的規劃查詢計劃。EXPLAIN INSERT INTO example SELECT * FROM ossexample; QUERY PLAN ---------------------------------------------------------------------- Insert on example (cost=0.00..1.10 rows=0 width=0) -> Foreign Scan on ossexample (cost=0.00..1.10 rows=1 width=998) Foreign OssDir: osstest/ Number Of Ossfile: 2
您也可以將example表中的數據寫入到OSS中。
INSERT INTO ossexample SELECT * FROM example;
更多oss_fdw相關參數說明請參見下文。
oss_fdw參數
oss_fdw和其他fdw接口一樣,對外部數據OSS中的數據進行封裝。用戶可以像使用數據表一樣通過oss_fdw讀取OSS中存放的數據。oss_fdw提供相應參數用于連接和解析OSS上的文件數據。
目前oss_fdw支持讀取和寫入OSS中文件的格式為:csv或者gzip格式的csv文件。
CREATE SERVER參數
參數 | 說明 |
host | 內網訪問OSS的Endpoint(地域節點)。 |
id | 賬號的AccessKey ID,具體請參見創建AccessKey。 |
key | 賬號的AccessKey Secret,具體請參見創建AccessKey。 |
bucket | OSS的bucket名稱,需要先創建OSS賬號再設置該參數。 |
針對導入模式和導出模式,提供下列容錯相關參數。網絡條件較差時,可以調整以下參數,以保障導入和導出成功。
參數 | 說明 |
oss_connect_timeout | 設置連接超時,單位秒,默認是10秒。 |
oss_dns_cache_timeout | 設置DNS超時,單位秒,默認是60秒。 |
oss_speed_limit | 設置能容忍的最小速率,默認是1024,即1K。 |
oss_speed_time | 設置能容忍最小速率的最長時間,默認是15秒。 |
如果使用了oss_speed_limit和oss_speed_time的默認值,表示如果連續15秒的傳輸速率小于1K,則超時。
CREATE FOREIGN TABLE參數
參數 | 說明 |
filepath | OSS中帶路徑的文件名。與dir任選一個即可,配置為此參數時,只支持從OSS將數據導入到RDS PostgreSQL中。
|
dir | OSS中的虛擬文件目錄。 與filepath任選一個即可,配置為此參數時,支持從OSS與RDS PostgreSQL互相導入導出數據。
|
prefix | 指定數據文件對應路徑名的前綴,不支持正則表達式,且與 filepath、dir 互斥,三者只能設置其中一個。 |
format | 指定文件的格式,目前只支持csv。 |
encoding | 文件中數據的編碼格式,支持常見的pg編碼,如utf8。 |
parse_errors | 讀取OSS中數據時的容錯模式解析,以行為單位,忽略文件分析過程中發生的錯誤。 重要 本參數不支持RDS PostgreSQL向OSS寫入數據的場景。如果您需要將RDS PostgreSQL的數據寫入到OSS中,請不要配置該參數。 |
delimiter | 指定列的分割符。 |
quote | 指定文件的引用字符。 |
escape | 指定文件的逃逸字符。 |
null | 指定匹配對應字符串的列為null,例如null ‘test’,即列值為’test’的字符串為null。 |
force_not_null | 指定某些列的值不為null。例如, |
compressiontype | 設置讀取和寫入OSS上文件的格式:
|
compressionlevel | 設置寫入OSS的壓縮格式的壓縮等級,范圍1到9,默認為6。 |
filepath和dir需要在OPTIONS參數中指定。
filepath和dir必須指定兩個參數中的其中一個,且不能同時指定。
導出模式目前只支持虛擬文件夾的匹配模式,即只支持dir,不支持filepath。
CREATE FOREIGN TABLE的導出模式參數
oss_flush_block_size:單次刷出到OSS的buffer大小,默認32MB,可選范圍1到128MB。
oss_file_max_size:寫入OSS的最大文件大小,超出之后會切換到另一個文件續寫。默認1024MB,可選范圍8到4000 MB。
num_parallel_worker:寫OSS數據的壓縮模式中并行壓縮線程的個數,范圍1到8,默認并發數3。
輔助函數
FUNCTION oss_fdw_list_file (relname text, schema text DEFAULT 'public')
用于獲得某個外部表所匹配的OSS上的文件名和文件的大小。
文件大小的單位是字節。
SELECT * FROM oss_fdw_list_file('ossexample');
name | size
--------------------------------+-----------
osstest/test.gz.1 | 739698350
osstest/test.gz.2 | 739413041
osstest/test.gz.3 | 739562048
(3 rows)
輔助功能
oss_fdw.rds_read_one_file:在讀模式下,指定某個外表匹配的文件。設置后,該外部表在數據導入中只匹配這個被設置的文件。
SET oss_fdw.rds_read_one_file = 'osstest/test.gz.2';
SELECT * FROM oss_fdw_list_file('ossexample');
name | size
--------------------------------+-----------
oss_test/test.gz.2 | 739413041
(1 rows)
oss_fdw注意事項
oss_fdw是在PostgreSQL FOREIGN TABLE框架下開發的外部表插件。
數據導入的性能和PostgreSQL集群的資源(CPU、IO、MEM)相關,也和OSS相關。
為保證數據導入的性能,請確保云數據庫PostgreSQL與OSS所在Region相同,相關信息請參見OSS endpoint 信息。
如果讀取外表的SQL時觸發
ERROR: oss endpoint userendpoint not in aliyun white list
,建議使用阿里云各可用區公共endpoint,詳情請參見訪問域名和數據中心。
錯誤處理
導入或導出出錯時,日志中會出現下列錯誤提示信息:
code:出錯請求的HTTP狀態碼。
error_code:OSS的錯誤碼。
error_msg:OSS的錯誤信息。
req_id:標識該次請求的UUID。當您無法解決問題時,可以憑req_id來請求OSS開發工程師的幫助。
請參見以下鏈接中的文檔了解和處理各類錯誤,超時相關的錯誤可以使用oss_ext相關參數處理。
ID和Key隱藏
CREATE SERVER中的ID和Key信息如果不做任何處理,用戶可以使用select * from pg_foreign_server
看到明文信息,會暴露用戶的ID和Key。我們通過對ID和Key進行對稱加密實現對ID和Key的隱藏(不同的實例使用不同的密鑰,最大限度保護用戶信息),但無法使用類似GP一樣的方法,增加一個數據類型,會導致老實例不兼容。
最終加密后的信息如下:
postgres=# SELECT * FROM pg_foreign_server ;
srvname | srvowner | srvfdw | srvtype | srvversion | srvacl | srvoptions
-----------+----------+--------+---------+------------+--------+------------------------------------------------------------------------------------------------------------------------------------
----------------------------------
ossserver | 10 | 16390 | | | | {host=oss-cn-hangzhou-zmf.aliyuncs.com,id=MD5****,key=MD5****,bucket=067862}
加密后的信息將會以MD5開頭(總長度為len,len%8==3),這樣導出之后再導入不會再次加密,但是用戶不能創建MD5開頭的Key和ID。