The oss_fdw extension is a foreign data wrapper (FDW) for ApsaraDB RDS for PostgreSQL that maps Object Storage Service (OSS) buckets to PostgreSQL foreign tables. Use it to query CSV files in OSS without importing them first, load large datasets into your RDS instance, or export table data to OSS for archiving and downstream processing.
Prerequisites
Before you begin, make sure you have:
An RDS instance running PostgreSQL 10 or later
If your instance runs PostgreSQL 14: a minor engine version of 20220830 or later. To upgrade, see Update the minor engine version
An OSS bucket in the same region as your RDS instance (recommended for performance). See Activate OSS and Create a bucket
An AccessKey ID and AccessKey Secret with read/write access to the bucket. See Obtain an AccessKey pair
How it works
oss_fdw maps one or more OSS objects to a PostgreSQL foreign table. Queries against the foreign table trigger a scan of the matched objects in OSS — no data is copied to your RDS instance until you explicitly insert it. All OSS objects must be in CSV format, with optional gzip compression.
To use oss_fdw:
Install the extension.
Create a server that holds your OSS connection credentials.
Create a foreign table that maps to the OSS objects you want to read or write.
Query or write through the foreign table.
Set up oss_fdw
Step 1: Install the extension
CREATE EXTENSION oss_fdw;Step 2: Create a server
The server stores your OSS endpoint, credentials, and bucket name. All connections from the foreign table go through this server.
CREATE SERVER ossserver FOREIGN DATA WRAPPER oss_fdw OPTIONS (
host 'oss-cn-hangzhou-internal.aliyuncs.com',
id '<your-access-key-id>',
key '<your-access-key-secret>',
bucket '<your-bucket-name>'
);| Placeholder | Description |
|---|---|
<your-access-key-id> | Your AccessKey ID |
<your-access-key-secret> | Your AccessKey Secret |
<your-bucket-name> | The name of your OSS bucket |
Use the internal endpoint for your region to avoid public network traffic. To find the endpoint: log in to the OSS console, open the bucket, and check the Endpoint value on the Overview page.
For all CREATE SERVER parameters — including fault tolerance tuning — see Server parameters.
Step 3: Create a foreign table
Define a foreign table whose column schema matches the structure of the CSV files in OSS.
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'
);The column schema must exactly match the structure of the OSS objects. A mismatch causes import errors.
The dir option points to an OSS folder. Everything in that folder (excluding subfolders) is included. To target specific files instead, use filepath — but note that filepath supports import only; dir supports both import and export.
For all CREATE FOREIGN TABLE parameters, see Foreign table parameters.
Import data from OSS
Read directly from OSS without loading data into your RDS instance:
SELECT * FROM ossexample;Load data into a local table for faster subsequent queries:
Create a local table with the same schema:
CREATE TABLE example ( date text, time text, open float, high float, low float, volume int );Insert data from the foreign table:
INSERT INTO example SELECT * FROM ossexample;
Before importing, run EXPLAIN to estimate the number of OSS objects matched and get the query plan:
EXPLAIN INSERT INTO example SELECT * FROM ossexample;Expected output:
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: 2Export data to OSS
Write data from a local table to OSS:
INSERT INTO ossexample SELECT * FROM example;For export, the foreign table must use the dir option (not filepath). Each export writes objects to the specified OSS folder.
To control output file size and parallelism, use the write-specific parameters in Foreign table parameters.
Server parameters
Use these parameters in the OPTIONS clause of CREATE SERVER.
Connection parameters
| Parameter | Description |
|---|---|
host | The internal OSS endpoint for your region. Find this on the bucket Overview page in the OSS console. |
id | Your AccessKey ID. |
key | Your AccessKey Secret. |
bucket | The name of your OSS bucket. |
Fault tolerance parameters
If you experience network connectivity issues, adjust these parameters to prevent premature timeout errors.
| Parameter | Default | Unit | Description |
|---|---|---|---|
oss_connect_timeout | 10 | seconds | Connection timeout. |
oss_dns_cache_timeout | 60 | seconds | DNS record cache timeout. |
oss_speed_limit | 1024 | bit/s | Minimum acceptable transmission rate (equivalent to 1 Kbit/s). |
oss_speed_time | 15 | seconds | Maximum time the transmission rate can stay below oss_speed_limit before a timeout error is triggered. |
With the defaults, a timeout error occurs if the transfer rate stays below 1 Kbit/s for 15 consecutive seconds.
Foreign table parameters
Use these parameters in the OPTIONS clause of CREATE FOREIGN TABLE.
File selection parameters
Specify exactly one of filepath, dir, or prefix.
| Parameter | Supports | Description |
|---|---|---|
filepath | Import only | The object name or prefix pattern to match. Does not include the bucket name. Matches objects named filepath and filepath.1, filepath.2, ... (consecutive integers starting from 1). A gap in the sequence stops matching — for example, if filepath.5 exists but filepath.4 does not, filepath.5 is not imported. |
dir | Import and export | The OSS folder to read from or write to. Must end with /. Matches all objects directly in the folder; subfolders and their contents are excluded. |
prefix | — | A path prefix to match objects. Does not support regular expressions. |
Format parameters
| Parameter | Description |
|---|---|
format | File format. Only csv is supported. |
encoding | Character encoding. Supports common PostgreSQL encodings, including utf8. |
delimiter | Column delimiter character. |
quote | Quote character for field values. |
escape | Escape character. |
null | String to interpret as NULL. For example, null 'test' treats the value test as NULL. |
force_not_null | Column name whose empty values are read as empty strings instead of NULL. For example, force_not_null 'id' stores empty id values as '' rather than NULL. |
Compression parameters
| Parameter | Default | Description |
|---|---|---|
compressiontype | none | Compression format. Use none for uncompressed or gzip for gzip-compressed objects. |
compressionlevel | 6 | Compression level for write operations only. Valid values: 1–9. |
Fault tolerance parameters
| Parameter | Description |
|---|---|
parse_errors | Number of row-level parse errors to tolerate during import. Rows that fail to parse are silently skipped. Not supported for export — do not set this parameter when writing to OSS. |
Write-specific parameters
These parameters apply only when writing data to OSS.
| Parameter | Default | Range | Unit | Description |
|---|---|---|---|---|
oss_flush_block_size | 32 | 1–128 | MB | Buffer size for each write to OSS. |
oss_file_max_size | 1024 | 8–4000 | MB | Maximum size of a single OSS output object. When this limit is reached, data continues into a new object. |
num_parallel_worker | 3 | 1–8 | threads | Number of parallel threads used to compress data during write. |
Auxiliary tools
List matched objects
oss_fdw_list_file returns the name and size of every OSS object matched by a given foreign table.
Signature:
oss_fdw_list_file(relname text, schema text DEFAULT 'public')Parameters:
| Parameter | Type | Description |
|---|---|---|
relname | text | The name of the foreign table. |
schema | text | The schema that contains the foreign table. Defaults to public. |
Return columns:
| Column | Type | Description |
|---|---|---|
name | text | The full OSS object path, relative to the bucket root. |
size | bigint | Object size in bytes. |
Example:
SELECT * FROM oss_fdw_list_file('ossexample');Output:
name | size
--------------------------------+-----------
osstest/test.gz.1 | 739698350
osstest/test.gz.2 | 739413041
osstest/test.gz.3 | 739562048
(3 rows)Read a single object
oss_fdw.rds_read_one_file limits a foreign table scan to one specific object. Applies to import only.
SET oss_fdw.rds_read_one_file = 'osstest/test.gz.2';
SELECT * FROM oss_fdw_list_file('ossexample');Output:
name | size
--------------------------------+-----------
oss_test/test.gz.2 | 739413041
(1 rows)Reset this parameter to resume normal multi-object scanning.
Protect your credentials
If the id and key values in CREATE SERVER are stored in plaintext, any database user with access to pg_foreign_server can read your AccessKey pair:
SELECT * FROM pg_foreign_server;To protect your credentials, use symmetric encryption on the id and key values when creating the server. Use a different encryption key for each RDS instance. When encrypted, the values appear as MD5**** in pg_foreign_server:
ossserver | 10 | 16390 | | | | {host=oss-cn-hangzhou-zmf.aliyuncs.com,id=MD5****,key=MD5****,bucket=067862}Each encrypted value starts with MD5, and the total length divided by 8 equals 3. After encrypted values are exported, they are not re-encrypted. AccessKey IDs and secrets that start with MD5 cannot be created — the encryption prefix is reserved.
Unlike Greenplum, oss_fdw does not support adding data types during encryption, which preserves compatibility with earlier PostgreSQL versions.Usage notes
Place your RDS instance and OSS bucket in the same region to maximize import and export throughput. See OSS domain names for endpoint details.
oss_fdwreads and writes only CSV format, including gzip-compressed CSV.Import performance depends on CPU, I/O, and memory available on your RDS instance.
parse_errorsis supported for reads only. Setting it on an export foreign table is not allowed.filepathis for import only. For export, usedir.The
filepathanddiroptions are mutually exclusive. Specify exactly one.
Troubleshooting
Error: oss endpoint not in allow list
If you see the error ERROR: oss endpoint userendpoint not in aliyun white list when querying a foreign table, switch to the public OSS endpoint for your region. See Regions and endpoints.
Import or export failures
When an operation fails, OSS returns error details in the PostgreSQL log:
| Field | Description |
|---|---|
code | HTTP status code of the failed request. |
error_code | Error code returned by OSS. |
error_msg | Error message returned by OSS. |
req_id | UUID of the failed request. Include this value when submitting a support ticket. |
For a full list of OSS error codes, see:
Timeout errors can also be resolved by tuning the fault tolerance parameters in Server parameters.