dblink や postgres_fdw などの PostgreSQL 拡張を使用して、テーブルに対するデータベース間の操作を実行できます。
背景情報
Alibaba Cloud は、ApsaraDB RDS for PostgreSQL のクラウドディスクインスタンスで dblink および postgres_fdw 拡張を有効にします。これらの拡張は、自己管理型 PostgreSQL データベースを含む、同じ VPC 内にあるインスタンス間のデータベース間の操作をサポートします。
注意事項
dblink および postgres_fdw を使用してデータベース間の操作を行う際は、次の点にご注意ください。
-
同じ VPC 内にある ECS インスタンスと ApsaraDB RDS for PostgreSQL インスタンスは、データベース間の操作を直接実行できます。
-
自己管理型 PostgreSQL インスタンスは、oracle_fdw または mysql_fdw を使用して VPC 外の Oracle インスタンスまたは MySQL インスタンスに接続できます。
-
同じインスタンス内の異なるデータベースに接続する場合:
-
IPv6 が有効なインスタンスでの接続失敗を防ぐため、ホストを
localhostではなく127.0.0.1に設定してください。 -
ポートを明示的に設定しないでください。ポート番号は、メンテナンスや仕様変更の際に変更される可能性があり、接続障害につながる可能性があります。ポートを省略すると、データベースは自動的に現在のポートを使用するため、接続の有効性が確保されます。
-
ポートを明示的に設定する必要がある場合は、データベースに接続し、
SHOW PORT;SQL 文を実行して現在のポート番号を照会してから設定してください。
-
-
ApsaraDB RDS for PostgreSQL インスタンスの VPC CIDR ブロック (例:
172.XX.XX.XX/16) を、宛先データベースの IP アドレスホワイトリストに追加してください。説明VPC CIDR ブロックは、お使いの ApsaraDB RDS for PostgreSQL インスタンスの [データベース接続] ページで確認できます。

dblink
-
dblink 拡張を作成します。
create extension dblink; -
dblink 接続を作成します。
postgres=> select dblink_connect('<connection_name>', 'host=<internal_endpoint_of_the_destination_instance> port=<listening_port_of_the_destination_instance> user=<destination_database_username> password=<password> dbname=<destination_database_name>'); postgres=> SELECT * FROM dblink('<connection_name>', '<sql_command>') as <table_name>(<column_name> <column_type>);例
postgres=> select dblink_connect('a', 'host=pgm-bpxxxxx.pg.rds.aliyuncs.com port=3433 user=testuser2 password=passwd1234 dbname=postgres'); postgres=> select * from dblink('a','select * from products') as T(id int,name text,price numeric); // 宛先データベースのテーブルをクエリします。
詳細については、「dblink ドキュメント」をご参照ください。
postgres_fdw
-
新しいデータベースを作成します。
postgres=> create database <database_name>; // データベースを作成します。 postgres=> \c <database_name> // 新しいデータベースに切り替えます。例
postgres=> create database db1; CREATE DATABASE postgres=> \c db1 -
postgres_fdw 拡張を作成します。
db1=> create extension postgres_fdw; -
宛先データベースの外部サーバーを作成します。
db1=> CREATE SERVER <server_name> FOREIGN DATA WRAPPER postgres_fdw OPTIONS (host '<internal_endpoint_of_the_destination_instance>', port '<listening_port_of_the_destination_instance>', dbname '<destination_database_name>'); db1=> CREATE USER MAPPING FOR <local_database_username> SERVER <server_name> OPTIONS (user '<destination_database_username>', password '<destination_database_password>');例
db1=> CREATE SERVER foreign_server1 FOREIGN DATA WRAPPER postgres_fdw OPTIONS (host 'pgm-bpxxxxx.pg.rds.aliyuncs.com', port '3433', dbname 'postgres'); CREATE SERVER db1=> CREATE USER MAPPING FOR testuser SERVER foreign_server1 OPTIONS (user 'testuser2', password 'passwd1234'); CREATE USER MAPPING -
外部テーブルをインポートします。
db1=> import foreign schema public from server foreign_server1 into <schema_name>; // 外部テーブルをインポートします。 db1=> select * from <schema_name>.<table_name> // 宛先データベースのテーブルをクエリします。例
db1=> import foreign schema public from server foreign_server1 into ft; IMPORT FOREIGN SCHEMA db1=> select * from ft.products;
詳細については、「postgres_fdw ドキュメント」をご参照ください。
よくある質問
Q: postgres_fdw を使用してパーティション化された外部テーブルをインポートするにはどうすればよいですか。
A: 宛先インスタンスでは、親パーティションテーブルをインポートするだけで、個々のパーティションをインポートする必要はありません。次の例では、レンジパーティションテーブルを使用します。
-- ソースインスタンス:ソースデータベース
CREATE TABLE sales (id int, p_name text, amount int, sale_date date) PARTITION BY RANGE (sale_date);
CREATE TABLE sales_2022_Q1 PARTITION OF sales FOR VALUES FROM ('2022-01-01') TO ('2022-03-31');
CREATE TABLE sales_2022_Q2 PARTITION OF sales FOR VALUES FROM ('2022-04-01') TO ('2022-06-30');
CREATE TABLE sales_2022_Q3 PARTITION OF sales FOR VALUES FROM ('2022-07-01') TO ('2022-09-30');
CREATE TABLE sales_2022_Q4 PARTITION OF sales FOR VALUES FROM ('2022-10-01') TO ('2022-12-31');
INSERT INTO sales VALUES (1,'prod_A',100,'2022-02-02');
INSERT INTO sales VALUES (2,'prod_B', 5,'2022-05-02');
INSERT INTO sales VALUES (3,'prod_C', 5,'2022-08-02');
INSERT INTO sales VALUES (4,'prod_D', 5,'2022-11-02');
-- 宛先インスタンスで実行します。パーティションではなく、親パーティションテーブルのみをインポートします。
import FOREIGN SCHEMA public limit to (sales) from server pg_fdw_server into public;
select * from sales;
次の結果が返されます。

Q: pg_net と postgres_fdw の違いは何ですか。
A: ApsaraDB RDS for PostgreSQL は、pg_net と postgres_fdw の両方の拡張をサポートしています。これらは異なるプロトコルを使用し、ユースケースも異なります。pg_net 拡張は、HTTP/HTTPS 経由でリクエストを送信して RESTful API または Webhook を呼び出しますが、PostgreSQL プロトコルを使用するデータベースにはアクセスできません。postgres_fdw 拡張は、PostgreSQL プロトコルを介して他の PostgreSQL データベースに接続し、データベース間のクエリとデータアクセスを実行します。