Фоновые задачи
Как контролировать завершение резервного копирования PostgreSQL
Связываем pg_dump, проверку архива и внешний сигнал. Разделяем завершение команды, доставку heartbeat и восстановимость копии.
Доступная база данных и работающий сервер не подтверждают наличие свежей резервной копии. Контроль бэкапа стоит привязать к завершению конкретной работы: созданию архива, его проверке и, если нужно, переносу в отдельное хранилище. Только после этой точки отправляйте heartbeat.
Разделите три результата
- Команда резервного копирования завершилась без ошибки.
- Созданный артефакт прошёл предусмотренные вами проверки и оказался в нужном месте.
- Внешний сервис принял сигнал об успехе.
Пропуск сигнала может означать сбой на любом из этих этапов. Он не устанавливает причину и не заменяет журнал задачи. Мониторинг cron и бэкапов следит за ожидаемым сигналом, а не читает содержимое вашей базы.
Минимальная обёртка для pg_dump
Пример предполагает PostgreSQL с настроенной аутентификацией через .pgpass или другой штатный механизм.
Не передавайте пароль в командной строке. Задайте имя базы, существующий закрытый каталог и секретный URL через окружение.
Запускайте скрипт в окружении с совместимыми pg_dump и pg_restore.
#!/usr/bin/env bash
set -euo pipefail
umask 077
: "${PGDATABASE:?Задайте имя базы}"
: "${BACKUP_DIR:?Задайте существующий каталог резервных копий}"
: "${HEARTBEAT_URL:?Задайте URL из настроек монитора}"
archive=$(mktemp "$BACKUP_DIR/backup-XXXXXXXX.dump")
trap 'rm -f -- "$archive"' EXIT
pg_dump --format=custom --file="$archive" "$PGDATABASE"
test -s "$archive"
pg_restore --list "$archive" >/dev/null
trap - EXIT
curl --fail --silent --show-error \
--connect-timeout 5 --max-time 15 "$HEARTBEAT_URL"mktemp создаёт уникальный файл, а trap удаляет только этот файл при незавершённом создании или проверке архива.
После успешной проверки trap снимается: ошибка доставки heartbeat не удаляет готовую копию.
Скрипт не удаляет старые резервные копии и не задаёт политику хранения.
pg_restore --list проверяет чтение оглавления custom-архива. Это не полное восстановление и не доказательство
целостности всех данных. Регулярно восстанавливайте копию в изолированную тестовую базу и проверяйте прикладные данные.
Роли и прочие глобальные объекты требуют отдельного плана резервного копирования.
Если обещанный результат задачи — копия во внешнем хранилище, добавьте выгрузку и проверку её результата до curl.
Локальный файл и загруженный объект — разные точки успеха. Не считайте локальный архив достаточным при потере всего сервера.
Настройте срок ожидания
В Heartbeat-мониторе выберите cron-режим и ожидаемое расписание.
В Uptimely оно задаётся шестью полями с секундами, в UTC. Например, 0 0 3 * * * — ежедневно в 03:00 UTC.
Системный cron обычно использует пять полей и часовой пояс сервера; согласуйте оба расписания.
Если копирование обычно занимает 12 минут, а иногда 18, grace period должен учитывать наблюдаемую длительность, выгрузку и доставку сигнала. Выбор конкретного запаса зависит от ваших замеров и допустимой задержки обнаружения. Разбор окна ожидания показывает, почему одинаковый запас не подходит всем задачам.
Проверьте контроль без риска для данных
Сначала выполните пример на отдельной тестовой базе и закрытом каталоге. Проверьте, что ошибка pg_dump
не приводит к сигналу, а ошибка доставки сигнала сохраняет готовый архив. Не отключайте сеть production ради эксперимента.
На отдельном мониторе проверьте сигнал, пропуск, уведомление и восстановление. После этого подключите рабочее расписание и дождитесь первого настоящего завершения. Храните URL в секрете: чужой запрос может скрыть отсутствие вашей резервной копии.
Подключение к расписанию разобрано в примере cron и curl, настройки монитора — в документации.