16.3 Foreign Data Wrappers
Foreign Data Wrapper(FDW)는 SQL/MED 표준의 PostgreSQL 구현. 외부 시스템(다른 PG, MySQL, Oracle, MongoDB, S3, CSV 파일, REST API 등)을 PostgreSQL 테이블처럼 만들어 SQL로 join·필터링 가능합니다.
동작 구조
flowchart LR
C["client"]
PG["PostgreSQL"]
FDW["FDW (postgres_fdw)"]
REMOTE["다른 시스템<br/>(다른 PG, MySQL, file 등)"]
C -->|SELECT * FROM foreign_table| PG
PG --> FDW
FDW -->|libpq, JDBC, REST...| REMOTE
classDef pg fill:#ede9fe,stroke:#6d28d9,color:#3b0764
classDef fdw fill:#dbeafe,stroke:#1d4ed8,color:#1e3a8a
classDef remote fill:#d1fae5,stroke:#047857,color:#064e3b
class PG pg
class FDW fdw
class REMOTE remote
표준 FDW들
| FDW | 대상 |
|---|---|
postgres_fdw (contrib) | 다른 PostgreSQL |
file_fdw (contrib) | CSV·텍스트 파일 |
oracle_fdw | Oracle |
mysql_fdw | MySQL/MariaDB |
mongo_fdw | MongoDB |
tds_fdw | MS SQL Server, Sybase |
redis_fdw | Redis |
s3_fdw / parquet_s3_fdw | S3 + Parquet |
kafka_fdw | Kafka |
http_fdw, multicorn | 임의의 REST/Python 구현 |
postgres_fdw — 가장 흔함
CREATE EXTENSION postgres_fdw;
-- 외부 서버 정의
CREATE SERVER remote_pg
FOREIGN DATA WRAPPER postgres_fdw
OPTIONS (host 'remote.example.com', port '5432', dbname 'app_main');
-- 사용자 매핑 (local user → remote user)
CREATE USER MAPPING FOR app_user
SERVER remote_pg
OPTIONS (user 'remote_user', password 'secret');
-- 단일 테이블 가져오기
CREATE FOREIGN TABLE remote_orders (
id bigint, user_id bigint, status text, ...
) SERVER remote_pg
OPTIONS (schema_name 'public', table_name 'orders');
-- 또는 스키마 전체 import (PG 9.5+)
IMPORT FOREIGN SCHEMA public
LIMIT TO (orders, users)
FROM SERVER remote_pg
INTO local_remote_schema;사용:
SELECT * FROM remote_orders WHERE status = 'pending';
-- 또는 로컬 테이블과 join
SELECT l.name, count(*)
FROM users l
JOIN remote_orders r ON l.id = r.user_id
GROUP BY l.name;Predicate pushdown
옵티마이저가 WHERE·LIMIT·집계를 원격 서버에서 직접 실행하도록 push.
EXPLAIN (VERBOSE) SELECT * FROM remote_orders WHERE status = 'pending';
-- Foreign Scan on remote_orders
-- Remote SQL: SELECT id, user_id, status FROM public.orders WHERE status = 'pending'Remote SQL이 원격에서 실행된 쿼리. WHERE가 push되면 네트워크 부하 ↓.
PG 16+에서 aggregate pushdown·join pushdown까지 — 매우 강력. postgres_fdw가 다른 PG에 대한 FDW라 가장 잘 됩니다.
file_fdw — CSV 파일
CREATE EXTENSION file_fdw;
CREATE SERVER files FOREIGN DATA WRAPPER file_fdw;
CREATE FOREIGN TABLE sales_csv (
date date, product text, amount numeric
) SERVER files
OPTIONS (filename '/var/data/sales.csv', format 'csv', header 'true');
SELECT * FROM sales_csv WHERE date >= '2026-05-01';ETL 진입점·외부 데이터 조회에 유용합니다.
운영 사용 사례
1. 데이터 통합 view
CREATE VIEW all_orders AS
SELECT 'production' AS source, * FROM local_orders
UNION ALL
SELECT 'analytics', * FROM remote_analytics_orders;여러 PostgreSQL을 한 가상 dataset으로.
2. 마이그레이션 단계
-- 옛 Oracle에서 새 PG로 점진적 이전
CREATE EXTENSION oracle_fdw;
CREATE SERVER oracle_db ...;
CREATE FOREIGN TABLE legacy_customers ...;
-- 두 DB 동시에 보면서 점진 마이그레이션3. 분산 read
큰 데이터를 다른 호스트에 두고 가끔 read:
SELECT * FROM remote_archive WHERE created_at < '2024-01-01' AND id = 42;
-- 1 row만 push되는 효율적인 fetch4. 읽기 전용 cache 검증
SELECT count(*) FROM local_table WHERE id NOT IN (SELECT id FROM remote_table);복제 검증·데이터 일관성 점검합니다.
쓰기
PG 9.3+에서 INSERT·UPDATE·DELETE도 가능 (postgres_fdw·oracle_fdw 등).
INSERT INTO remote_orders (user_id, status) VALUES (42, 'pending');
UPDATE remote_orders SET status = 'paid' WHERE id = 100;원격 시스템에 직접 쓰기. 분산 트랜잭션은 PostgreSQL 자체로 보장 안 함 — 한 쪽 실패하면 일관성 깨질 수 있습니다.
성능 주의
| 함정 | 영향 |
|---|---|
| 큰 테이블 SELECT * | 모든 row가 네트워크 통과 — 느림 |
| pushdown 안 되는 WHERE (함수 호출) | 모든 row fetch 후 로컬 필터 |
| 통계 누락 | 옵티마이저가 plan 정확도 ↓ |
| 인덱스 활용은 원격의 인덱스 | local 인덱스 무관 |
| network round trip | 작은 쿼리 많이 = 네트워크 비용 큼 |
-- 통계 갱신
ANALYZE remote_orders;use_remote_estimate = true 옵션으로 원격의 통계를 사용 — plan 정확도 ↑.
보안
- 사용자 매핑에 password를 평문으로 두지 말 것 —
pgpass또는 secret manager - 원격에 최소 권한 role로만 접근
- 원격 서버의 SSL 강제 (
sslmode = require) - 매니지드 클라우드는 outbound network 정책 점검
한계
| 한계 | 메모 |
|---|---|
| 분산 트랜잭션 (2PC) | postgres_fdw가 부분 지원 (postgres_fdw.use_two_phase_commit) — 모든 FDW가 아님 |
| 일관 스냅샷 | 없음 — 원격 쿼리가 다른 시점 |
| FK·constraint | 외부 테이블에 정의 안 됨 |
| 인덱스 | 외부 테이블에 직접 못 만듦 |
| 쿼리 plan time | 매번 원격 통계 조회 가능 |
대안
| 패턴 | 메모 |
|---|---|
| logical replication | 동기 복제 — FDW보다 성능 ↑, 단방향 |
| ETL (Airbyte, Fivetran) | 주기적 데이터 이동 |
| dblink | FDW 이전의 방식. 함수 호출 기반 — 인터페이스 어색 |
| Citus | 분산 PG 확장 — sharding |
정리
- FDW = 외부 시스템을 SQL로 통합
- postgres_fdw가 가장 흔함. PG 16+ join·aggregate pushdown 강력
- file_fdw로 CSV·텍스트 파일도 테이블처럼
- 마이그레이션·통합 view·분산 read에 표준
- 성능은 pushdown 여부에 좌우
- 분산 트랜잭션은 부분 지원 — 일관성 보장 필요하면 logical replication
다음 절(16.4)에서는 DB 안에서 코드를 실행하는 — 절차적 언어를 봅니다.