阿里云支持通过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。