PostgreSQL

Foreign Data Wrappers

Что если обратиться к MySQL, S3-файлам и удалённому PostgreSQL одним SQL-запросом, без ETL и промежуточных таблиц?

  • Cloudflare агрегирует метрики из 250+ PoP через postgres_fdw без ETL-конвейеров
  • Supabase предоставляет parquet_s3_fdw пользователям для SQL-запросов к S3 без отдельного аналитического движка
  • GitHub выполняет параллельные запросы к 12 региональным кластерам через async FDW, сокращая время агрегации с 12 до 1.5 секунды

Концепция FDW

Foreign Data Wrappers (FDW) - это SQL/MED стандарт (ISO/IEC 9075-9), реализованный в PostgreSQL с версии 9.1. FDW позволяет обращаться к внешним источникам данных через стандартный SQL-интерфейс, как если бы они были локальными таблицами.

Архитектура FDW состоит из трёх уровней: Foreign Server (адрес и параметры подключения к источнику), User Mapping (маппинг локальных пользователей на учётные данные источника) и Foreign Table (виртуальная таблица, представляющая внешние данные).

PostgreSQL содержит реестр расширений-обёрток: file_fdw (встроен), postgres_fdw (встроен), а также сторонние: mysql_fdw, oracle_fdw, mongo_fdw, redis_fdw, parquet_s3_fdw и десятки других.

Cloudflare использует FDW для консолидации метрик из 250+ PoP-точек в центральную аналитическую базу без ETL-конвейеров. Каждый региональный PostgreSQL-кластер доступен через postgres_fdw с query pushdown - запросы с фильтрами по дате и региону передаются на удалённый сервер, а не вытягивают весь объём данных.

Какой стандарт лежит в основе FDW в PostgreSQL?

FDW реализует стандарт SQL/MED (Management of External Data), часть 9 стандарта ISO/IEC 9075.

postgres_fdw

postgres_fdw - самый функциональный FDW в экосистеме, поддерживает полный query pushdown: фильтры WHERE, JOIN, сортировку ORDER BY, агрегаты COUNT/SUM и даже UPDATE/DELETE на удалённых таблицах (начиная с PostgreSQL 9.3).

IMPORT FOREIGN SCHEMA - удобная альтернатива ручному CREATE FOREIGN TABLE. Синхронизирует структуру таблиц с удалённым сервером за одну команду.

Notion применяет postgres_fdw для федерации данных между шардами. При запросе workspace-метаданных, разбросанных по нескольким шардам, использование FDW с async_capable позволило сократить время ответа на 60% по сравнению с application-level aggregation - параллельные запросы выполняются одновременно.

postgres_fdw не поддерживает транзакции 2PC между локальным и удалённым серверами. Если транзакция успешно зафиксирована локально, но сеть упала до фиксации на удалённом - возникает partial commit. Для критичных операций использовать компенсирующие транзакции или saga-паттерн.

Что такое 'query pushdown' в контексте postgres_fdw?

Pushdown передаёт WHERE, GROUP BY, ORDER BY на удалённый сервер - данные фильтруются там, а не передаются целиком для локальной фильтрации.

mysql_fdw и другие сторонние FDW

mysql_fdw (EnterpriseDB) обеспечивает read/write доступ к MySQL и MariaDB из PostgreSQL. Поддерживает pushdown фильтров и сортировок, маппинг типов данных. Используется для миграции с MySQL или работы с legacy-системами.

Популярные сторонние FDW: oracle_fdw (Laurenz Albe) для Oracle Database, tds_fdw для MS SQL Server и Sybase, mongo_fdw для MongoDB, redis_fdw для Redis, parquet_s3_fdw для Parquet-файлов на S3, multicorn для написания FDW на Python.

Supabase использует parquet_s3_fdw в своём продукте Supabase Analytics - пользователи могут запрашивать данные из S3 через обычный SQL, без необходимости разворачивать отдельный аналитический движок.

Какой FDW позволяет запрашивать Parquet-файлы на S3 через SQL?

parquet_s3_fdw специализируется на работе с Parquet-файлами в S3-совместимых хранилищах через стандартный SQL-интерфейс.

file_fdw

file_fdw - встроенное расширение PostgreSQL для чтения файлов через SQL. Поддерживает CSV, TSV и любые форматы, совместимые с COPY FROM. Полезно для импорта данных из файловой системы без промежуточных этапов.

file_fdw предоставляет доступ только суперпользователю или пользователям с ролью pg_read_server_files. Файл читается с правами процесса PostgreSQL (обычно postgres), поэтому доступны только файлы, читаемые этим пользователем.

file_fdw удобен для разбора CSV-экспортов из других систем прямо в SQL-запросах, без необходимости создавать промежуточные таблицы через COPY.

Типичный use case: анализ PostgreSQL CSV-логов для обнаружения паттернов медленных запросов. Команда Dropbox использовала этот подход для ежедневного парсинга логов из 800+ инстансов: file_fdw + UNION ALL + агрегация дают отчёт о топ-100 медленных запросов за 5 минут без внешних инструментов.

Какой формат файлов поддерживает file_fdw?

file_fdw использует механизм COPY FROM, поэтому поддерживает все форматы, совместимые с этой командой: CSV, TSV, custom delimiter.

Query Pushdown и производительность FDW

Query pushdown - ключевой механизм производительности FDW. Планировщик PostgreSQL анализирует запрос и определяет, какие части можно выполнить на удалённом сервере, чтобы минимизировать объём передаваемых данных.

Факторы, блокирующие pushdown: локальные функции (не существующие на удалённом сервере), несовместимые типы данных, collation-конфликты, оператор ANY с локальным массивом. EXPLAIN VERBOSE покажет строку 'Remote SQL' - если её нет, pushdown не происходит.

GitHub использует postgres_fdw с async_capable для параллельного опроса 12 региональных PostgreSQL-кластеров при генерации глобальных отчётов. Асинхронный режим позволяет выполнять все 12 запросов параллельно, сокращая время агрегации с 12 секунд до 1.5 секунды.

При архитектуре с FDW стоит создавать STATISTICS на foreign tables через ANALYZE - планировщик сможет лучше оценить стоимость удалённых запросов и принять правильное решение о порядке JOIN.

FDW - это просто прозрачная репликация данных

FDW обеспечивает виртуальный доступ к внешним данным без их физического копирования. Данные остаются на источнике, каждый запрос выполняется через сетевое соединение. Для частых запросов к большим объёмам имеет смысл рассмотреть материализованные представления поверх FDW с периодическим REFRESH.

FDW обеспечивает виртуальный доступ через сетевые запросы при каждом обращении. Для частых запросов к большим объёмам имеет смысл создать материализованное представление поверх FDW с периодическим REFRESH - это локально кэшируует результаты.

Что блокирует query pushdown в postgres_fdw?

Локальные функции (UDF) нельзя выполнить на удалённом сервере, поэтому строки передаются локально для обработки. WHERE/GROUP BY/ORDER BY с встроенными функциями поддерживают pushdown.

Foreign Data Wrappers

  • FDW реализует SQL/MED стандарт: внешние источники выглядят как локальные таблицы
  • postgres_fdw поддерживает полный pushdown WHERE/GROUP BY/ORDER BY на удалённый PostgreSQL
  • mysql_fdw, parquet_s3_fdw, mongo_fdw расширяют доступ к гетерогенным источникам
  • file_fdw читает CSV/TSV файлы через SQL без промежуточного COPY
  • EXPLAIN VERBOSE показывает 'Remote SQL' - признак работающего pushdown

Связь с другими темами

FDW дополняет другие подходы к работе с распределёнными данными

  • Citus — Citus - горизонтальное масштабирование внутри PostgreSQL, FDW - доступ к внешним гетерогенным источникам
  • Логическая репликация — Логическая репликация копирует данные для локального хранения; FDW предоставляет виртуальный доступ без копирования
  • Материализованные представления — Matview поверх FDW-таблицы кэширует результаты удалённых запросов локально для повышения производительности

Вопросы для размышления

  • Когда предпочесть FDW вместо ETL-конвейера для интеграции с внешними системами?
  • Почему локальные UDF блокируют query pushdown и как это влияет на производительность?
  • Какие риски несёт запись в удалённые таблицы через FDW при сбое сети в момент транзакции?

Связанные уроки

  • db-17-nosql-overview
Foreign Data Wrappers

0

1

Войти