Логическая репликация PostgreSQL: слоты растут, подписка отстаёт
Логическая репликация PostgreSQL ломается тихо. Слот репликации фиксирует позицию в журнале предзаписи и удерживает её до подтверждения от подписчика — если подписка остановлена, отстала или не успевает применять изменения, основная база продолжает писать, а освободить журнал не может. Свободное место на разделе с данными уходит со скоростью записи, и останавливается не репликация, а сама база.
Дальше срабатывает цепочка: переполнение хранилища, журналу некуда писаться, запись встаёт. Остановка автоматической очистки мёртвых строк идёт следом, поэтому таблицы пухнут, а после освобождения места нужно ещё наверстать накопившееся отставание подписчика. Аварийный перезапуск основной базы в этот момент растягивается на часы недоступности записи: приложение получает отказы, а восстановление требует ручного разбора — какой слот держит журнал, насколько отстала подписка, какие таблицы разошлись.
Отставание подписчика редко имеет одну причину. Обычно складывается несколько: подписка ловит конфликт применения и падает в цикле, публикация перечисляет лишние таблицы, на подписчике не хватает ресурсов под нагрузку применения, а длинные транзакции на источнике держат снимок и не дают позиции сдвинуться. Без наблюдения за состоянием слотов репликации и отставанием подписки это замечают уже по заполненному диску.
Настройка репликации начинается с предохранителей: предел, сколько журнала слот вправе удерживать, отключение неиспользуемых слотов, ограничение списка публикуемых таблиц, измерение отставания подписки. Дальше разбираем, как это закрывается на практике.
Что меняется в эксплуатации: обновления без остановки сервиса
Логическая репликация передаёт изменения на уровне строк, а не копирует базу целиком, поэтому целевой контур остаётся живым и доступным на чтение всё время переноса. Публикация на источнике и подписка на приёмнике собираются так, чтобы переключение заняло минуты: сначала накатывается структура таблиц, затем данные, и только после сверки контрольных сумм трафик переводится на новую базу. Обновление структуры таблиц перестаёт быть событием с плановым окном простоя на ночь — это правка в рабочем режиме.
Отчётная нагрузка уходит на отдельный контур. Тяжёлые соединения, полные сканирования и агрегации больше не конкурируют за память, соединения и время процессора с транзакциями записи — очереди на блокировках между записью и аналитикой просто не воспроизводятся. Основная база обслуживает прикладной поток, и время отклика записи перестаёт зависеть от того, кто в этот момент строит отчёт.
Отдельный класс отказов, который уходит вместе с этим, — длительное окно блокировки и нехватка места при копировании базы целиком. Отраслевые разборы инцидентов при миграции, Отчёты по эксплуатации СУБД, показывают, что основная доля незапланированных простоев приходится именно на эти два сценария, а не на саму передачу изменений.
Практический результат: изменение схемы на боевой базе выполняется без остановки сервиса, отчётные запросы не влияют на прикладные, а возврат на прежний контур остаётся возможным на любом шаге, пока идёт сверка данных.
Режимы репликации: публикации, подписки и ограничения
Логическая репликация строится вокруг пары «публикация — подписка»: на источнике публикация описывает, какие таблицы и какие операции попадают в поток, на приёмнике подписка читает слот и применяет изменения. В отличие от полной копии кластера, поток собирается на уровне строк и таблиц, поэтому приёмник может быть другой конфигурации и принимать только часть схемы.
Отсюда и развилка: одна механика закрывает и перенос отдельных таблиц, и обмен между контурами, и выгрузку в аналитику. Выбор определяет, нужна ли запись на приёмнике, сколько таблиц участвует и кто отвечает за разрешение конфликтов.
| Вариант | Когда подходит | Ограничения |
|---|---|---|
| Полная копия кластера | Нужен дубль всего сервера: отказоустойчивость, восстановление | Передаётся кластер целиком, приёмник только для чтения, конфигурации должны совпадать |
| Выборочная передача таблиц | Нужна часть схемы: справочники, сервисные таблицы, переезд без остановки | Только таблицы с первичным ключом или настроенным идентификатором строк; изменения схемы переносятся вручную |
| Двусторонний обмен между контурами | Несколько площадок пишут одновременно, нужна сходимость данных | Требуется правило разрешения конфликтов: приоритет узла, последняя запись, отбрасывание дубля; риск циклов |
| Выгрузка через промежуточную очередь | Нужно развязать источник и потребителей, добавить фильтрацию и повтор | Задержка выше прямой подписки; нужен контроль смещения и повторной доставки |
| Передача в аналитический контур на чтение | Отчёты и аналитика не должны нагружать основной узел | Только чтение, обратной записи нет, правки в аналитике до источника не доедут |
Публикации и подписки не заменяют физическую репликацию: изменения схемы, последовательности и объекты вне таблиц переносятся отдельно. Правила разрешения конфликтов фиксируются до включения обмена — иначе расхождение всплывёт уже в данных.
Этапы работ: от аудита нагрузки до передачи в эксплуатацию
Логическая репликация переносит не копию страниц, а поток изменений, поэтому до запуска нужен профиль нагрузки: какие таблицы дают основной объём записи, как часто меняется схема, есть ли первичные ключи. Порядок этапов ниже не случаен — каждый следующий опирается на данные предыдущего.
- Аудит нагрузки и текущей схемы. Снимаем статистику по объёму и частоте изменений, длительным запросам, правам и составу объектов. Отдельно помечаем таблицы без первичного ключа — для них нужен свой подход.
- Проектирование схемы передачи данных. Фиксируем, что попадает в репликацию, а что остаётся локальным, как обходятся секвенции и изменения структуры. На выходе — схема потоков и список рисков с планом на каждый.
- Подготовка объектов и прав. Создаём роли репликации с минимально нужными правами, приводим идентификаторы реплики, сверяем версии и расширения на источнике и приёмнике.
- Настройка публикаций и подписок. Поднимаем публикацию на источнике и подписку на приёмнике, стартовую синхронизацию запускаем так, чтобы она не блокировала боевую запись и не тормозила приложения.
- Контроль отставания на боевом профиле. Наблюдаем отставание под реальной нагрузкой: пики записи, длинные транзакции, конфликты применения. Ставим оповещения с порогами, чтобы рост замечался до того, как станет критичным.
- Репетиция переключения нагрузки. Останавливаем запись, ждём нулевого отставания, переводим приложения на новый узел, проверяем последовательности и фоновые задания. Обратный откат проходим так же.
- Передача регламента эксплуатации. Отдаём документацию: как читать метрики отставания, что делать при конфликте, как добавить таблицу в публикацию. Дежурная смена разбирает сценарии на тестовом контуре.
Что остаётся в вашем контуре: конфигурации и регламенты
Работы по репликации заканчиваются не запущенной подпиской, а пакетом артефактов, который физически остаётся у вас. Ниже — то, что мы передаём в контур заказчика и без чего поток изменений живёт ровно до первой нештатной ситуации.
- Файлы параметров публикующей и подписывающейся стороны с комментариями, что изменено и почему: новый узел поднимается копированием, а не по памяти инженера.
- Описание объектов передачи и документация по репликации: какие таблицы входят в публикацию, что исключено осознанно, как обрабатываются последовательности и конфликты записи.
- Схема потоков данных: откуда изменения попадают в публикацию, через какие узлы идут, где можно разорвать поток без потери целостности.
- Матрица прав доступа: отдельные роли для публикации и подписки, кому разрешено читать состояние слотов и кто отвечает за мониторинг.
- Оповещения об отставании: пороги по задержке применения, адресаты и порядок эскалации — о расхождении узнаём до того, как его заметит бизнес.
- Инструкция дежурной смены: типовые сбои, как читать состояние подписки, в какой момент останавливать поток и кого поднимать.
- Регламент переключения и возврата к прежней схеме плюс памятка по восстановлению прерванной подписки — включая случай, когда слот на месте, но поток встал.
Разбор проекта: перенос отчётной нагрузки без простоя
Что было
Отчётный контур жил на том же сервере, что и боевая база PostgreSQL. Ночные обновления схемы требовали остановки записи на несколько часов, а тяжёлые аналитические выборки в пиковые часы держали блокировки и разгоняли отставание подписки до десятков минут. Дежурная смена разбирала такие обращения почти каждую смену: часть — из-за задержек отчётов, часть — из-за подвисших транзакций.
Что стало
Репликацию на боевом контуре развели на выделенный контур аналитики: публикация на конкретный набор таблиц, подписка со своим слотом и начальным копированием данных без остановки источника. Новые таблицы добавляются в публикацию отдельным шагом, конфликты по ключу снимаются повторным применением — обновление схемы больше не блокирует запись.
Метрики до и после: окно обновления схемы сократилось с нескольких часов до нуля, отставание реплики держится в пределах минуты даже в часы пик, на спокойной нагрузке — секунды. Обращения дежурной смены по отчётной нагрузке сократились вчетверо за первый месяц работы контура.
Замеры подтверждаются двумя источниками: графиком отставания реплики в системе контроля и журналом переключений подписки. Оба остаются у заказчика, поэтому деградацию видно до того, как её заметят пользователи отчётов.
Что делать, если уже развёрнута полная копия кластера?
Полная копия кластера и логическая подписка не конфликтуют — они работают на разных уровнях. Физическая реплика пересылает поток изменений всего кластера целиком, а логическая разбирает его на уровне таблиц и передаёт только те, что перечислены в публикации. Поэтому публикацию можно поднять на источнике рядом с уже работающей копией, дать подписке догнать и переключать потребителей постепенно, без остановки сервиса.
Настройки при этом переиспользуются: роли, права доступа, сетевые правила и слоты на целевом узле уже есть, публикация добавляется поверх. Первичную синхронизацию выбранных таблиц делаем не с нуля, а с текущей копии — она уже содержит актуальный срез, и остаётся догнать изменения по позиции в журнале. Переход укладывается в часы работы, а не в окно простоя.
Пока сосуществуют две схемы, источник истины остаётся один. Читающие потребители продолжают ходить прежним путём, а новые запросы направляем на выборочные таблицы и сверяем результат: число строк, контрольные суммы по ключевым таблицам, отставание подписки в секундах. Пока отставание не нулевое или сверка даёт расхождения, старый контур остаётся основным.
Отключаем его, когда подписка держит нулевое отставание под боевой нагрузкой и сверка проходит несколько раз подряд без расхождений. Порядок: остановить запись через прежний путь, убедиться, что последние изменения доехали, снять подписку, затем убрать физическую копию и освободить её дисковое место. Слот, оставленный без подписчика, — главная угроза: он копит журнал и забивает диск.
Технические сомнения: слоты, отставание, конфликты
Логическая репликация — это поток изменений из публикации в подписку, и сбои случаются не при запуске, а в нештатных режимах. Разбираем пять ситуаций, которые чаще всего всплывают уже в рабочем контуре.
Что будет, если подписчик выключен?
Изменения копятся в слоте на источнике: подписка помнит позицию и после включения продолжит с неё. Пока подписчик молчит, слот удерживает журнал, поэтому на источнике держим запас места.
Можно ли передавать часть таблиц?
Да, публикация собирается по списку таблиц или схем, остальное не покидает источник. Приёмники должны существовать заранее с совместимой структурой и первичным ключом.
Как быть с конфликтами при записи в оба контура?
Конфликтная строка останавливает применение, и подписка ждёт вмешательства. Мы разграничиваем зоны записи по таблицам, а расхождения разбирает правило разрешения, а не ручная правка строк.
Что происходит со слотами при простое?
Слот сохраняется, даже если подписка удалена, и продолжает удерживать журнал — отсюда переполнение диска. В регламент входят мониторинг отставания и удаление неиспользуемых слотов.
Нужно ли останавливать сервис при смене схемы?
Добавление колонки проходит на живой системе; смена типа или первичного ключа требует паузы подписки и повторной синхронизации таблицы. Порядок — приёмник, затем источник, потом поток.
Обсудим задачу: пришлите схему текущего контура
Чтобы вернуться с оценкой работ, а не с общими соображениями, нужен минимум вводных — обычно они уже есть у вашей команды. Чем точнее исходные данные, тем меньше уточняющих кругов и тем реалистичнее план работ по срокам.
- Схема текущего контура: где размещены источник и приёмник, как связаны по сети, есть ли промежуточные узлы и балансировщики.
- Список таблиц и последовательностей: что переносим целиком, что частично, где есть секционирование, внешние ключи и генерируемые значения.
- Требования к окну обновления: допустимое отставание приёмника, нужен ли перенос отдельных таблиц без остановки записи.
- Целевой контур: версия и редакция СУБД, направление репликации — односторонняя или двусторонняя, нужен ли каскад на несколько приёмников.
- Текущие системы контроля: сбор журналов, оповещения по отставанию слота репликации и по конфликтам применения изменений.
- Ограничения по нагрузке: профиль записи в пиковые часы, суточный объём изменений, поведение при обрыве связи.
Опишите задачу в свободной форме и приложите то, что уже есть — этого достаточно, чтобы начать. Мы вернёмся с оценкой и планом работ: этапами, порядком переключения и точками отката на каждом шаге.







