Foreign-Data Wrappers (FDW) — это такая фича в PostgreSQL, позволяющая обращаться к внешним СУБД, а также файлам, веб-сервисам, да и вообще к чему угодно. В настоящее время существует много готовых FDW , в том числе для Oracle, MySQL, Redis , MongoDB , ClickHouse, Kafka, Cassandra и RocksDB . Если нужный FDW еще не написан, вы можете реализовать его самостоятельно . Сегодня мы рассмотрим основы использования FDW, на примере доступа к одному серверу PostgreSQL с другого.
Для эксперимента был использован PostgreSQL 13.3. Первый сервер был запущен на виртуалке с Ubuntu Linux 20.04 LTS. На хост-системе под управлением MacOS Catalina был установлен второй сервер. С него мы будем ходить на первый сервер по FDW.
Сервер на виртуалке был настроен, как обычно . Был создан пользователь и принадлежащая ему БД. Файлы postgresql.conf и pg_hba.conf были изменены так, чтобы к БД можно было получить доступ по сети. Также была создана такая таблица:
id SERIAL PRIMARY KEY ,
name VARCHAR ( 64 ) ,
phone VARCHAR ( 64 ) ) ;
Проверяем, что к первому серверу (на виртуалке) можно получить доступ со второго (на хосте):
В данном случае используется проброс портов средствами VirtualBox, отсюда такие IP и порт.
На втором сервере также создаем непривилегированного пользователя и его БД:
CREATE USER mac_user WITH password ‘AppleForever’ ;
GRANT ALL ON DATABASE mac_db TO mac_user;
Будучи все еще под суперпользователем, подключаемся к mac_db и включаем расширение postgres_fdw:
CREATE EXTENSION postgres_fdw;
Расширение идет вместе с PostgreSQL и отдельно скачивать / компилировать его не нужно.
Указываем параметры подключения к серверу:
FOREIGN DATA WRAPPER postgres_fdw
OPTIONS ( dbname ‘test_database’ , host ‘127.0.0.1’ , port ‘5454’ ) ;
Проверяем:
List of foreign servers
Name | Owner | Foreign-data wrapper
—————+——-+———————-
ubuntu_server | eax | postgres_fdw
(1 row)
eax=# select * from pg_foreign_server;
-[ RECORD 1 ]————————————————
oid | 37539
srvname | ubuntu_server
srvowner | 10
srvfdw | 37532
srvtype |
srvversion |
srvacl |
srvoptions | {dbname=test_database,host=127.0.0.1,port=5454}
Говорим, в какого пользователя должен отображаться mac_user для доступа к удаленному серверу:
SERVER ubuntu_server
OPTIONS ( USER ‘test_user’ , password ‘qwerty’ ) ;
Проверяем:
-[ RECORD 1 ]——————————-
umid | 37542
srvid | 37539
srvname | ubuntu_server
umuser | 37541
usename | mac_user
umoptions | {user=test_user,password=qwerty}
Разрешаем mac_user ходить на удаленный сервер:
Теперь заходим под mac_user:
Важно! Имейте ввиду, что mac_user может прочитать пароли и явки для подключения к удаленному серверу, используя приведенные выше запросы.
Для доступа к таблице phonebook говорим:
FROM SERVER ubuntu_server INTO public;
… или:
( id SERIAL , name VARCHAR ( 64 ) , phone VARCHAR ( 64 ) )
SERVER ubuntu_server
OPTIONS ( schema_name ‘public’ , table_name ‘phonebook’ ) ;
Теперь с таблицей phonebook (или fdw_phonebook) можно работать, как если бы она была локальной. Все изменения с таблицей, которые мы делаем на втором сервере, будут видны на первом, и наоборот.
Если таблица больше не нужна, от нее можно избавиться так:
При этом на удаленном сервере таблица продолжит существовать.
Foreign-Data Wrappers обеспечивают доступ к разным СУБД через одну точку доступа. Это удобно при выполнении аналитических запросов, а также с некоторой долей успеха позволяет горизонтально масштабировать PostgreSQL на запись. Еще FDW полезен при миграции на PostgreSQL с неправильных СУБД.