Что такое логическая репликация в PostgreSQL и чем она отличается от физической?
Суть механизма
Логическая репликация в PostgreSQL — способ передавать изменения данных между базами на уровне логических объектов: строк и таблиц, а не физических страниц диска. В отличие от потоковой (physical) репликации, где реплика получает побайтовую копию WAL и является полной копией кластера, логическая репликация декодирует записи WAL в последовательность логических операций (INSERT, UPDATE, DELETE, TRUNCATE) с помощью механизма logical decoding и выходного плагина, обычно встроенного pgoutput.
Publication и Subscription
Механизм построен на двух сущностях:
- Publication создаётся на стороне источника и определяет набор таблиц, изменения которых будут транслироваться.
- Subscription создаётся на стороне приёмника, подключается к publication и применяет полученные изменения локально.
При создании подписки сервер сначала делает начальную копию данных (snapshot) выбранных таблиц, а затем переходит в режим потокового применения изменений.
Как это работает изнутри
- На источнике должен быть выставлен
wal_level = logical. - Для каждой подписки создаётся replication slot, который гарантирует, что WAL не будет удалён, пока изменения не доставлены подписчику.
- Walsender читает WAL, logical decoding превращает записи в логические изменения, плагин pgoutput сериализует их в протокол репликации.
- На стороне подписчика процесс apply worker применяет изменения построчно, используя обычные SQL-операции.
Отличие от физической репликации
- Физическая: копия всего кластера, идентичная версия PostgreSQL, читать данные с реплики можно, но структура жёстко привязана к мастеру.
- Логическая: можно реплицировать отдельные таблицы или базы, версии PostgreSQL на источнике и приёмнике могут отличаться, на приёмнике можно писать в нереплицируемые таблицы, удобно для миграций с минимальным даунтаймом и для построения ETL/аналитических копий.
Ограничения
- DDL не реплицируется автоматически — схему нужно синхронизировать вручную.
- Последовательности (sequences) не реплицируются, их значения нужно синхронизировать отдельно.
- Для UPDATE/DELETE таблице нужен PRIMARY KEY или REPLICA IDENTITY, иначе операции завершатся ошибкой.
- Крупные объекты (large objects) не поддерживаются.
- Начальная синхронизация больших таблиц может создавать заметную нагрузку.
Типичные сценарии применения
- Миграция на новую мажорную версию PostgreSQL с минимальным простоем.
- Репликация части данных в другую систему (например, для аналитики или шардирования).
- Двусторонняя (multi-master) синхронизация отдельных таблиц между регионами.
Что хочет услышать интервьюер
Кандидат объясняет, что логическая репликация работает на уровне строк таблиц через WAL и logical decoding
Упоминает publication/subscription и replication slot
Чётко проговаривает отличие от физической (streaming) репликации
Знает про требование wal_level = logical и необходимость primary key/replica identity
Может привести практический сценарий использования (миграция версий, частичная репликация)
Пример: Настройка publication и subscription
-- На сервере-источнике
ALTER SYSTEM SET wal_level = 'logical';
-- требуется перезапуск сервера
-- создаём публикацию для конкретных таблиц
CREATE PUBLICATION orders_pub FOR TABLE orders, order_items;
-- На сервере-приёмнике: создаём такие же таблицы заранее,
-- затем подписываемся на изменения
CREATE SUBSCRIPTION orders_sub
CONNECTION 'host=source_host dbname=shop user=repl_user password=secret'
PUBLICATION orders_pub;
-- проверка статуса репликации на источнике
SELECT slot_name, active, restart_lsn FROM pg_replication_slots;
-- проверка статуса на приёмнике
SELECT subname, pid, received_lsn, latest_end_lsn FROM pg_stat_subscription;
Типичные ошибки
Путают логическую репликацию с обычной потоковой (streaming) репликацией
Не знают, что DDL и последовательности не реплицируются автоматически
Забывают, что для UPDATE/DELETE нужен primary key или REPLICA IDENTITY
Считают, что логическая репликация всегда быстрее или легче физической
Не упоминают replication slot и риск разрастания WAL при неактивной подписке


