Привет, Хабр! Я Виктор, руковожу отделом разработки в Хайстекс. Как только очередной вендор обещает «убить нативные тулзы PostgreSQL», где-то устало вздыхает DBA. Попытка сделать бэкап PostgreSQL «лучше самого PostgreSQL» — это изначально неверная постановка задачи. 

Универсальный файловый агент не притворяется глубоко PostgreSQL-aware решением. Его задача в другом: взять нативные механизмы СУБД и превратить их в управляемый и наблюдаемый процесс на уровне всей инфраструктуры.

Вокруг такого подхода обычно сразу возникают неприятные, но правильные вопросы. Кто отвечает за консистентность? Где на самом деле живет PITR? Что будет, если потеряется WAL-сегмент? Можно ли восстановить одну таблицу, а не весь инстанс? И зачем вообще нужен внешний слой поверх pg_probackup, если у PostgreSQL уже есть свои зрелые инструменты?

Ниже — честный разговор о границах ответственности между PostgreSQL и внешней платформой.

1. Где заканчивается PostgreSQL и начинается платформа

  • Зачем вообще нужен отдельный слой, если у PostgreSQL уже есть свои механизмы бэкапа, WAL и PITR, а на практике существуют зрелые инструменты вроде pg_probackup?

Консистентность, WAL и PITR должен обеспечивать сам PostgreSQL и его нативные инструменты. У универсального агента другая зона ответственности: запуск сценариев вокруг бэкапа, работа с хранилищем, централизованные политики, контроль выполнения и стандартизированное восстановление.

Задача

Кто отвечает

Консистентность данных PostgreSQL

PostgreSQL / нативные утилиты

WAL-архивирование

PostgreSQL / нативные утилиты

PITR

PostgreSQL / нативные утилиты

Учет особенностей версии PostgreSQL

PostgreSQL-aware скрипты и шаблоны

Оркестрация и расписания

Акура

Массовое управление десятками инстансов

Акура

Единый контроль, статусы, алерты, аудит

Акура

Политики хранения и восстановления

Акура

Если совсем коротко: PostgreSQL отвечает за корректность бэкапа, платформа — за эксплуатацию этого процесса в масштабе и управляемо.

  • СРК или просто планировщик? Если всю «магию» (запуск бэкапа, проверку прав) админ пишет сам в скриптах, в чем тогда ценность Акуры?

Проблемы начинаются не там, где нужно один раз вызвать pg_backup_start() или pg_basebackup. Они начинаются, когда в инфраструктуре появляются:

  • разные версии PostgreSQL;

  • разные хосты и среды;

  • разные окна резервного копирования;

  • разные требования к retention;

  • разный уровень дисциплины у команд;

  • ручные ошибки;

  • отсутствие единой картины по всей инфраструктуре.

Поэтому PostgreSQL должен отвечать за свою внутреннюю механику, а платформа — за все вокруг нее. Поддержка pre/post-скриптов – нормальная граница ответственности, которая позволяет не изобретать собственный «псевдо-PostgreSQL-бэкап», а встроить в систему нативный сценарий.

  • запуск pg_backup_start() / pg_backup_stop();

  • проверка прав;

  • WAL-архивирование;

  • валидация;

  • логика с учетом версии PostgreSQL.

На практике платформа здесь нужна для того чтобы:

  • централизованно запускать и контролировать скрипты;

  • стандартизировать шаблоны для разных БД;

  • собирать статусы и ошибки в одном контуре;

  • управлять хранением и восстановлением;

  • снижать операционный риск.

  • Как управлять всем этим, если баз в инфраструктуре не две, а пятьдесят?

На двух базах можно жить на shell-скриптах. На пятидесяти это уже плохо масштабируется: разные версии PostgreSQL, разные команды, разные окна бэкапа, разные правила и отсутствие общей картины. В такой ситуации выигрывает тот, у кого есть единый слой управления. На масштабе важнее не только качество самого бэкапа, сколько качество управления всем процессом.

Чтобы дальше не путаться в терминах и ожиданиях, вот краткая сводка, что в решении уже есть, а чего пока нет.

Возможность

Статус

Полный бэкап

Есть

Инкрементальный бэкап

Нет

Непрерывный WAL ingestion

Нет

Собственная PITR-логика

Нет

Восстановление в отдельную директорию

Есть

Восстановление одной таблицы

Нет

Watchdog зависшего backup mode

Нет

Централизованный контроль скриптов

Есть

2. Целостность и PITR (Point-in-Time Recovery)

  • PITR требует постоянного архивирования WAL. Акура будет просто копировать папку раз в сутки или она умеет «подхватывать» новые логи по мере их появления? Если лог «съест» ротация или он не доедет — восстановление станет невозможным?

Здесь ответ простой: без непрерывного WAL-архива PITR не бывает. Копировать каталог раз в сутки и называть это PITR нельзя. 

В текущем варианте агент не реализует WAL-aware логику: он не подхватывает WAL непрерывно, не контролирует LSN-цепочку и не реализует собственный PITR. Поэтому в нашем случае схема такая:

  • PostgreSQL-aware скрипты обеспечивают base backup и архивирование WAL;

  • платформа оркестрирует, мониторит и управляет этими процессами.

Если WAL-сегмент потерян, удален ротацией раньше времени или не доехал до хранилища, цепочка PITR действительно рвется. Никакая платформа это не «обходит». Ее задача в другом: вовремя заметить разрыв, поднять тревогу и не дать такой ошибке остаться незамеченной.

  • Если скрипт отработал с ошибкой, но Акура этого не поняла и забэкапила неконсистентные данные — получит ли админ уведомление о ошибке?

Корректный принцип такой: если native backup script завершился ошибкой, backup не должен считаться успешным. Он должен завершаться в статусе failed, а администратор должен получать сигнал.

Что есть в текущем коде:

  • бэкап умеет запускать pre/post scripts;

  • если скрипт вернул non-zero exit code, HTTP-запрос завершается ошибкой, если не включен ignore_scripts_errors;

  • при ignore_scripts_errors=true ошибка может быть проигнорирована, и для production PostgreSQL это опасный режим.

Поэтому нормальная конфигурация для PostgreSQL — не игнорировать такие ошибки и поднимать их в общий контур мониторинга. Это как раз один из реальных аргументов в пользу платформенного слоя: не «умный бэкап», а единое обнаружение, эскалация и отчетность по ошибкам.

  • Если пост-скрипт не выполнится, база останется в режиме бэкапа навсегда. Это приведет к лавинообразному росту логов и остановке БД из-за нехватки места. Есть ли в Акуре контроль «зависших» сессий?

Да, это реальный риск. Если выход из backup mode не сработает, WAL может начать расти лавинообразно, а дальше все упрется в диск. Встроенного watchdog’а для такого сценария сейчас нет, поэтому одного файлового агента здесь недостаточно. Нужен отдельный защитный слой: контроль длительности backup-сессии, мониторинг роста WAL, контроль свободного места и автоматическая эскалация аномалий. Зрелость платформы проверяется не обещаниями, а тем, как она ведет себя в аварийных сценариях.

3. Эффективность и ресурсы

  • Будет ли Акура каждый раз перекачивать по сети все терабайты файлов базы, или она умеет передавать только изменившиеся блоки внутри сегментов?

Пока поддерживается только полный бэкап. Инкрементальный режим еще не реализован. Это значит, что агент каждый раз пересканирует каталог и передает весь снапшот. При этом архитектура уже блочная: файлы разбиваются на выровненные блоки. Это дает основу для инкрементальных оптимизаций в следующих версиях.

  • Что если база весит 2 ТБ, а свободного места на диске всего 500 ГБ? Умеет ли Акура стримить бэкап сразу в хранилище, не создавая локальную копию на диске сервера?

Агент не создает рядом с базой еще одну полную локальную копию. Он сохраняет снапшот и метаданные в meta_store_dir, а сами данные читает блоками из исходного каталога и сразу отправляет в хранилище.

Поэтому сценарий «база занимает 2 ТБ, а свободного места на сервере 500 ГБ» с точки зрения локального диска возможен. Но дальше все упирается в пропускную способность дисков, сети и самого хранилища. Это сильная сторона подхода. Но чудес здесь нет: если база тяжелая, упираетесь не только в механику бэкапа, но и в пропускную способность дисков, сети и хранилища.

  • Если делать бэкапы часто, не «положит» ли СРК дисковую подсистему постоянными чекпоинтами?

Сам бэкап не управляет чекпоинтами PostgreSQL. Он создает другую нагрузку: читает дерево файлов, сканирует и стримит данные. То есть риск есть, но он другой:

  • не «платформа создает свои чекпоинты»;

  • частые full backups тяжелых каталогов создают заметный read I/O.

Отсюда следует нормальная архитектурная позиция: для PostgreSQL нельзя ограничиться идеей «давайте просто часто запускать файловый бэкап». Нужна комбинация:

  • base backup;

  • непрерывный WAL-архив;

  • разумные окна резервного копирования;

  • лимиты и приоритеты;

  • централизованная политика частоты запуска.

Проблема здесь не в «чужих чекпоинтах», а в read I/O от частых полных бэкапов. Поэтому для PostgreSQL обычно нужна комбинация из base backup, непрерывного WAL-архива и централизованной политики частоты запуска.

4. Восстановление

  • Если нужно спасти одну таблицу, придется ли админу перезатирать всю рабочую базу бэкапом? Или Акура позволяет восстановиться в «соседнюю» временную папку для ручного вытаскивания данных?

Если нужно вернуть одну таблицу, заливать весь бэкап поверх рабочей базы — плохая идея. Рабочий сценарий здесь другой:

  • восстановить backup в соседнюю локацию или временный инстанс;

  • проверить целостность;

  • извлечь нужный объект;

  • аккуратно перенести его в production.

В текущей реализации можно восстанавливать данные в указанную recovery_location, и это хорошо ложится на такой сценарий. Но переоценивать возможности не стоит: агент работает на файловом уровне. Он не умеет «восстановить одну таблицу» как объект PostgreSQL. Для этого нужен либо отдельный скрипт, либо следующий этап развития решения.

  • Как минимизировать количество ручных действий при восстановлении?

Восстановление не должно зависеть от того, кто сегодня дежурит. Нужен стандартный сценарий, а не героизм DBA. Нормальный шаблон восстановления выглядит так:

  • выбор точки восстановления;

  • восстановление в безопасную локацию;

  • валидация;

  • извлечение нужного объекта или переключение на восстановленный экземпляр;

  • фиксация результата и аудит операции.

Сейчас этот сценарий автоматизирован не полностью. Но именно здесь платформенный слой действительно полезен: он делает recovery повторяемым и управляемым.

5. Безопасность и хранение

  • Откуда скрипт возьмет пароль для подключения к базе? Будет ли он зашит в скрипте в открытом виде или Акура предоставляет защищенное хранилище для секретов?

Пароль не должен жить в shell-скрипте в открытом виде. Для продакшена это неприемлемо. Встроенного хранилища секретов в текущей реализации нет. Поэтому рабочая схема такая:

  • нативные PostgreSQL скрипты используют секреты, полученные из защищенного внешнего механизма;

  • Акура как платформа может интегрироваться с secret management и передавать секреты в runtime безопасным способом.

Вызвать pg_basebackup несложно. Сложно сделать это безопасно, предсказуемо и одинаково на десятках инстансов.

  • Есть ли в системе логирование действий пользователей? Есть ли ответ на вопрос «Кто и когда изменил расписание бэкапа критической БД?»

Аудит изменений пока не реализован.

  • Кто управляет ротацией WAL-логов в удаленном хранилище? Не окажется ли S3 забито старыми файлами, которые Акура боится удалять, не зная их важности для СУБД?

WAL retention в текущей реализации не автоматизирован. Более того, даже persisted snapshots в meta_store_dir пока не ротируются сами.

Здесь проблема очевидна: если удалять WAL без понимания backup chain, можно незаметно сломать восстановление. Если не удалять вообще — хранилище начнет бесконтрольно расти.

Поэтому retention должен управляться централизованно и по понятным правилам, а не набором локальных скриптов на хостах.

6. Совместимость

  • Есть ли у Акуры проверенные шаблоны под современные версии (Postgres 15+), где эксклюзивный режим бэкапа больше не поддерживается?

Для PostgreSQL 15+ нельзя опираться на старый exclusive backup mode. Нужен актуальный non-exclusive сценарий. Здесь подход с хуками и скриптами под конкретную версию PostgreSQL выглядит разумно: логика СУБД не вшивается намертво в универсальный агент.

Но и тут стоит быть честными, готовых PostgreSQL-specific шаблонов «из коробки» сейчас нет: скрипты в репозитории пока общие, а не PostgreSQL-native. Отсюда вывод:

  • направление выбрано правильно;

  • шаблон для продакшена должен учитывать конкретную версию PostgreSQL;

  • делать это лучше через хуки и скрипты, а не через жестко зашитую логику в агенте.

  • Какие лимиты «нативного» подхода вы признаете открыто?

Здесь легко уйти в крайности. Либо сказать, что нативных инструментов всегда достаточно. Либо, наоборот, что без отдельной платформы жить нельзя. Обе позиции упрощают картину.

На небольшом количестве инстансов и при сильной DBA-команде нативных инструментов PostgreSQL действительно может хватить. Но на масштабе у такого подхода быстро появляются ограничения:

  • много ручной работы;

  • конфигурационный дрейф;

  • разные практики на разных хостах;

  • отсутствие единого аудита;

  • сложный и неодинаковый recovery-процесс.

В этот момент и появляется смысл у внешнего слоя оркестрации.

Лимиты есть у любого подхода. Нативные средства (pg_probackup, WAL-G) лучше всех знают механику Постгреса. Если у вас пара баз и сильная команда DBA, вам их хватит.

Но на десятках инстансов нативные утилиты оставляют слишком много ручной работы, повышают риск конфигурационного дрейфа и не дают прозрачного аудита. Акура берет правильные механизмы СУБД и оборачивает их в промышленный пайплайн. БД отвечает за консистентность и WAL, платформа – за оркестрацию, контроль, алерты и хранение. Такое разделение ответственности работает надежнее всего.

Как вы сейчас решаете проблему масштабирования бэкапов? Делитесь опытом в комментариях.