Use OSS Foreign Table to access Iceberg data
Query Apache Iceberg tables stored in OSS directly from AnalyticDB for PostgreSQL using OSS Foreign Data Wrapper (FDW)—no data import required.
Apache Iceberg is an open table format for enormous analytic datasets. It provides features such as version control, schema evolution, partition evolution, and efficient queries. With Iceberg support in AnalyticDB for PostgreSQL, you can:
-
Query Iceberg tables directly without importing data
-
Use the Massively Parallel Processing (MPP) engine to accelerate large-scale Iceberg analysis
-
Run join queries between local tables and Iceberg foreign tables
-
Share data with Iceberg-compatible systems such as Hive, Spark, StarRocks, and EMR
Version requirements
AnalyticDB for PostgreSQL 7.0 instances with kernel version 7.3.0.0 or later.
To check your kernel version, go to the Basic Information page of your instance in the AnalyticDB for PostgreSQL console. To upgrade, see Update the minor version of the instance.
Prerequisites
Before you begin, make sure you have:
Permissions:
-
An Alibaba Cloud account or a Resource Access Management (RAM) user with
AliyunGPDBFullAccess,AliyunECSFullAccess,AliyunEMRFullAccess, andAliyunOSSFullAccesspermissions -
An AccessKey ID and AccessKey secret for the account. See Create an AccessKey pair
Network connectivity:
-
The AnalyticDB for PostgreSQL instance and the OSS bucket are in the same region
-
The EMR cluster (or other Iceberg write tool such as Flink, StarRocks, or Doris) and the AnalyticDB for PostgreSQL instance are in the same VPC
Data readiness:
-
Iceberg tables and data already exist in the OSS bucket. See Create an OSS bucket
Limitations
Storage:
-
Only OSS is supported as the underlying storage system. OSS-HDFS and external HDFS are not supported.
Metadata services:
-
Supported: Hive Metastore (HMS) and directory-based Hadoop Catalog
-
The HMS connection address must be an internal same-region endpoint to ensure network connectivity between the AnalyticDB for PostgreSQL master node and HMS
Supported operations:
-
Read-only (SELECT). INSERT, UPDATE, and DELETE are not supported.
File formats:
-
Iceberg tables must use ORC or Parquet as the underlying file format.
Choose a catalog type
AnalyticDB for PostgreSQL supports three Iceberg catalog types. Choose based on your environment:
| Catalog type | catalog_type value |
When to use | Notes |
|---|---|---|---|
| Hive Catalog | hive |
You have an EMR cluster with Hive Metastore | Requires HMS URI (thrift://<host>:9083); supports high-availability HMS |
| Hadoop Catalog | hadoop |
You use a directory-based Iceberg warehouse on OSS | Requires warehouse path on OSS |
| DMS OneMeta | onemeta |
You manage Iceberg metadata in Alibaba Cloud DMS | Requires a support ticket before use |
Use hive or hadoop for most deployments. To use DMS OneMeta, submit a ticket to contact technical support.
Step 1: Create an OSS server
Run CREATE SERVER to define the OSS server and specify the Iceberg catalog configuration.
Syntax
CREATE SERVER <server_name>
FOREIGN DATA WRAPPER oss_fdw
OPTIONS (
endpoint '<endpoint>', -- Internal OSS endpoint for your region
bucket '<bucket_name>', -- OSS bucket name
catalog_type '<catalog_type>',
-- Additional catalog parameters (see table below)
);
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
server_name |
STRING | Yes | Name of the OSS server |
endpoint |
STRING | Yes | Internal OSS endpoint. Only internal endpoints are supported. See Regions and endpoints for endpoint values. |
bucket |
STRING | No | OSS bucket name. Must be set in at least one of the server or the foreign table. If set on both, the foreign table value takes precedence. |
catalog_type |
STRING | Yes | Iceberg catalog type: hive, hadoop, or onemeta. |
hms_uris |
STRING | No | HMS URL in the format thrift://<host>:<port>. Default port: 9083. Required for catalog_type=hive. For high-availability HMS, specify multiple addresses separated by commas. Before configuring this parameter, add an inbound rule for port 9083 to the security group of the EMR cluster master node. |
warehouse |
STRING | No | OSS path of the Iceberg warehouse. Required for catalog_type=hadoop. |
dms_endpoint |
STRING | No | DMS endpoint. Required for catalog_type=onemeta. See Service registration for endpoint values by region. |
dms_region |
STRING | No | DMS region ID. Required for catalog_type=onemeta. |
For more details, see Use OSS Foreign Table for data lake analytics.
Step 2: Create a user mapping
Run CREATE USER MAPPING to map an AnalyticDB for PostgreSQL database user to the credentials used to access OSS. See CREATE USER MAPPING for the PostgreSQL reference.
Syntax
CREATE USER MAPPING FOR { <username> | USER | CURRENT_USER | PUBLIC }
SERVER <server_name>
OPTIONS (
id '<AccessKey_ID>', -- AccessKey ID for OSS
key '<AccessKey_secret>', -- AccessKey secret for OSS
-- For DMS OneMeta only:
dms_id '<AccessKey_ID>', -- AccessKey ID for DMS
dms_key '<AccessKey_secret>' -- AccessKey secret for DMS
);
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
username |
STRING | Yes (one of four) | Database username to map. Use PUBLIC to create a mapping that applies to all current and future database users. |
USER |
STRING | — | Maps the current database user. |
CURRENT_USER |
STRING | — | Maps the current session user. |
PUBLIC |
STRING | — | Creates a public mapping for all database users. |
server_name |
STRING | Yes | Name of the OSS server to map to. |
id |
STRING | Yes | AccessKey ID for OSS access. See Create an AccessKey pair. |
key |
STRING | Yes | AccessKey secret for OSS access. See Create an AccessKey pair. |
dms_id |
STRING | No | AccessKey ID for DMS OneMeta. Configure only when catalog_type=onemeta. Can be the same as id. |
dms_key |
STRING | No | AccessKey secret for DMS OneMeta. Configure only when catalog_type=onemeta. Can be the same as key. |
Step 3: Create an OSS foreign table
Run CREATE FOREIGN TABLE to create a foreign table that maps to an existing Iceberg table. See CREATE FOREIGN TABLE for the PostgreSQL reference.
Iceberg data types are automatically mapped to AnalyticDB for PostgreSQL types—for example, BIGINT maps to bigint and STRING maps to text. Before creating the foreign table, check the OSS Foreign Table data type mapping table to confirm column type compatibility.
Syntax
CREATE FOREIGN TABLE <table_name> (
<column_name> <data_type>
[, ...]
)
SERVER <server_name>
OPTIONS (
format 'iceberg',
database_name '<database_name>', -- Iceberg database name
table_name '<iceberg_table_name>', -- Iceberg table name
-- For DMS OneMeta only:
dms_catalog_name '<catalog_name>'
);
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
table_name |
STRING | Yes | Name of the OSS foreign table in AnalyticDB for PostgreSQL. |
column_name |
STRING | Yes | Column name. |
data_type |
STRING | Yes | Column data type. |
server_name |
STRING | Yes | Name of the OSS server. |
format |
STRING | Yes | Set to iceberg. |
database_name |
STRING | Yes | Iceberg database name. Full OSS path: oss://<bucket>/<warehouse>/<database_name>. |
table_name (OPTIONS) |
STRING | Yes | Iceberg table name. Full OSS path: oss://<bucket>/<warehouse>/<database_name>/<table_name>. |
dms_catalog_name |
STRING | No | DMS OneMeta catalog name. Configure only when catalog_type=onemeta. Find the name in the DMS consoleDMS console. |
Step 4: Query Iceberg data
After creating the foreign table, query Iceberg data like any standard table:
SELECT * FROM <table_name>;
SELECT COUNT(*) FROM <table_name>;
Examples
Example 1: Hadoop Catalog (directory-based)
This example uses EMR to write Iceberg data to OSS, then queries it from AnalyticDB for PostgreSQL using a Hadoop Catalog.
Step 1: Log on to the EMR cluster
Use SSH to log on to the EMR cluster.
Step 2: Start Spark SQL with Iceberg support
spark-sql \
--conf spark.sql.extensions=org.apache.iceberg.spark.extensions.IcebergSparkSessionExtensions \
--conf spark.sql.catalog.hadoop=org.apache.iceberg.spark.SparkCatalog \
--conf spark.sql.catalog.hadoop.type=hadoop \
--conf spark.sql.catalog.hadoop.warehouse=oss://testBucketName/warehouse
Replace oss://testBucketName/warehouse with your actual OSS warehouse path.
When the prompt changes to spark-sql>, Spark SQL is ready.
Step 3: Create an Iceberg table and write data
-- Create a database
CREATE DATABASE IF NOT EXISTS hadoop.hadoop_db;
-- Create a table and insert sample data
CREATE TABLE IF NOT EXISTS hadoop.hadoop_db.hadoop_sample(
id BIGINT COMMENT 'unique id',
data STRING
)
USING iceberg;
INSERT INTO hadoop.hadoop_db.hadoop_sample VALUES (1, 'a'), (2, 'b'), (3, 'c');
Verify the data:
SELECT * FROM hadoop.hadoop_db.hadoop_sample;
Step 4: Verify the OSS file structure
In the OSS console, confirm the Iceberg files exist at the following paths:
oss://testBucketName/warehouse/hadoop_db/hadoop_sample/
├── metadata/
│ ├── metadata.json
│ ├── snapshots.avro
│ └── manifests.avro
└── data/
└── parquet files...
Step 5: Create the Iceberg foreign table in AnalyticDB for PostgreSQL
Run the following SQL in AnalyticDB for PostgreSQL:
-- Create an OSS server
CREATE SERVER oss_hadoop_srv
FOREIGN DATA WRAPPER oss_fdw
OPTIONS (
endpoint 'oss-cn-hangzhou-********.aliyuncs.com',
bucket 'testBucketName',
catalog_type 'hadoop',
warehouse 'oss://testBucketName/warehouse'
);
-- Create a user mapping
CREATE USER MAPPING FOR PUBLIC
SERVER oss_hadoop_srv
OPTIONS (
id 'LTAI****************', -- AccessKey ID for OSS
key 'yourAccessKeySecret' -- AccessKey secret for OSS
);
-- Create a foreign table
CREATE FOREIGN TABLE sample (
id BIGINT,
data text
)
SERVER oss_hadoop_srv
OPTIONS (
format 'iceberg',
database_name 'hadoop_db',
table_name 'hadoop_sample'
);
Step 6: Query the data
SELECT * FROM sample;
Example 2: Hive Catalog (Hive Metastore)
This example uses Hive Metastore to manage Iceberg metadata.
Step 1: Log on to the EMR cluster
Use SSH to log on to the EMR cluster.
Step 2: Start Spark SQL with Hive Catalog support
spark-sql \
--conf spark.sql.extensions=org.apache.iceberg.spark.extensions.IcebergSparkSessionExtensions \
--conf spark.sql.catalog.hive=org.apache.iceberg.spark.SparkCatalog \
--conf spark.sql.catalog.hive.type=hive
When the prompt changes to spark-sql>, Spark SQL is ready.
Step 3: Create an Iceberg table and write data
-- Create a database with OSS as the storage location
CREATE DATABASE IF NOT EXISTS hive.hive_db
COMMENT 'Database stored on OSS'
LOCATION 'oss://testBucketName/warehouse/hive_db.db/';
-- Create a table and insert sample data
CREATE TABLE IF NOT EXISTS hive.hive_db.hive_sample(
id BIGINT COMMENT 'unique id',
data STRING
)
USING iceberg;
INSERT INTO hive.hive_db.hive_sample VALUES (1, 'a'), (2, 'b'), (3, 'c');
Verify the data:
SELECT * FROM hive.hive_db.hive_sample;
Step 4: Verify the OSS storage structure
In the OSS console, confirm the Iceberg files exist at the following paths:
oss://testBucketName/warehouse/hive_db.db/hive_sample/
├── metadata/
│ ├── metadata.json
│ ├── snapshots.avro
│ └── manifests.avro
└── data/
└── parquet files...
Step 5: Create the Iceberg foreign table in AnalyticDB for PostgreSQL
Run the following SQL in AnalyticDB for PostgreSQL:
-- Create an OSS server
CREATE SERVER oss_hive_srv
FOREIGN DATA WRAPPER oss_fdw
OPTIONS (
endpoint 'oss-cn-hangzhou-********.aliyuncs.com',
bucket 'testBucketName',
catalog_type 'hive',
hms_uris 'thrift://192.168.XXX.XXX:9083'
);
-- Create a user mapping
CREATE USER MAPPING FOR PUBLIC
SERVER oss_hive_srv
OPTIONS (
id 'LTAI****************', -- AccessKey ID for OSS
key 'yourAccessKeySecret' -- AccessKey secret for OSS
);
-- Create a foreign table
CREATE FOREIGN TABLE hive_sample (
id BIGINT,
data text
)
SERVER oss_hive_srv
OPTIONS (
format 'iceberg',
database_name 'hive_db',
table_name 'hive_sample'
);
Step 6: Query the data
SELECT * FROM hive_sample;
Example 3: DMS OneMeta
Before using DMS OneMeta as your Iceberg catalog, submit a ticket to enable this feature.
Step 1: Create the Iceberg foreign table in AnalyticDB for PostgreSQL
Based on the Iceberg table schema in DMS OneMeta, run the following SQL in AnalyticDB for PostgreSQL:
-- Create an OSS server
CREATE SERVER oss_dms_serv
FOREIGN DATA WRAPPER oss_fdw
OPTIONS (
endpoint 'oss-cn-hangzhou-********.aliyuncs.com',
bucket 'testBucketName',
catalog_type 'onemeta',
dms_endpoint '<dms_endpoint_name>',
dms_region '<dms_region_id>'
);
-- Create a user mapping
CREATE USER MAPPING FOR PUBLIC
SERVER oss_dms_serv
OPTIONS (
id 'LTAI****************', -- AccessKey ID for OSS
key 'yourAccessKeySecret', -- AccessKey secret for OSS
dms_id 'LTAI****************', -- AccessKey ID for DMS
dms_key 'yourAccessKeySecret' -- AccessKey secret for DMS
);
-- Create a foreign table
CREATE FOREIGN TABLE sample (
id BIGINT,
data text
)
SERVER oss_dms_serv
OPTIONS (
format 'iceberg',
dms_catalog_name '<dms-catalog-name>',
database_name '<dms-database-name>',
table_name '<dms-table-name>'
);
Step 2: Query the data
SELECT * FROM sample;
FAQ
How are Iceberg data types mapped to AnalyticDB for PostgreSQL types?
Iceberg types are automatically mapped to AnalyticDB for PostgreSQL types. For example, BIGINT maps to bigint and STRING maps to text. For the full mapping table, see OSS Foreign Table data type mapping.
Can I write to an Iceberg foreign table?
No. AnalyticDB for PostgreSQL only supports reading (SELECT) from Iceberg foreign tables. INSERT, UPDATE, and DELETE are not supported.
What do I do if the Iceberg table schema changes?
Recreate the foreign table DDL in AnalyticDB for PostgreSQL to reflect the updated schema.