Обычная streaming-репликация в PostgreSQL копирует кластер байт-в-байт — WAL одинаковый на всех репликах, и реплика обязана быть той же мажорной версии, что и мастер. Логическая репликация работает иначе: она декодирует WAL в поток изменений строк (insert/update/delete) и применяет их через обычный SQL. Из-за этого можно реплицировать не весь кластер, а отдельные таблицы, и версии publisher/subscriber могут отличаться — это штатный способ мигрировать между мажорными релизами без pg_upgrade и почти без простоя.

Настройка начинается с wal_level = logical в postgresql.conf (требует рестарта) и правила в pg_hba.conf для реплика-пользователя. На стороне-источнике:

CREATE PUBLICATION mypub FOR TABLE users, departments;

На принимающей стороне:

CREATE SUBSCRIPTION mysub
  CONNECTION 'dbname=foo host=bar user=repuser'
  PUBLICATION mypub;

CREATE SUBSCRIPTION сама создаёт replication slot на publisher и поднимает воркер, который сначала копирует содержимое таблиц целиком, а затем применяет изменения непрерывно.

Платить приходится по нескольким пунктам: DDL не реплицируются (ALTER TABLE нужно накатывать руками на обе стороны синхронно), последовательности (sequences) синхронизируются только при первичном снапшоте, а не в реальном времени, а таблицы без primary key требуют REPLICA IDENTITY FULL, иначе UPDATE/DELETE не находят нужную строку на подписчике. Для выборочной миграции одной-двух таблиц или для апгрейда мажорной версии с минимальным окном недоступности это всё равно дешевле, чем полная физическая репликация с её жёсткой привязкой к версии.

#postgresql #dba