Как мониторить бэкапы базы данных

Обновлено 2 ноября 2026

Бэкапы ломаются буднично. Заканчивается место на диске, меняется пароль от базы, сервер пересобирают, а crontab на новый не переносят. Никто не жалуется, и проблема вскрывается в тот день, когда нужно восстанавливаться. Решение простое: пусть бэкап отчитывается о каждом запуске, а что-то другое замечает, если отчёт не пришёл.

Что может пойти не так

Скрипт бэкапа, который отчитывается

Этот Bash-скрипт для PostgreSQL закрывает все пять случаев. Он сообщает Heartcron о старте, отправляет любую ошибку с номером строки, проверяет размер дампа и при успехе шлёт пинг с размером в теле запроса:

#!/usr/bin/env bash
set -euo pipefail

PING=https://ping.heartcron.com/<uuid>
FILE=/var/backups/app-$(date +%F).sql.gz

# «запустился»: запуск, который так и не завершился, считается зависшим
curl -fsS -m 10 --retry 3 -o /dev/null "$PING/start" || true

# любая упавшая команда сразу сообщает об ошибке
trap 'curl -fsS -m 10 --retry 3 -o /dev/null --data-raw "failed at line $LINENO" "$PING/fail"' ERR

pg_dump "$DATABASE_URL" | gzip > "$FILE"

# дамп меньше 1 МБ — что-то не так; подберите порог под свою базу
SIZE=$(stat -c %s "$FILE")
if [ "$SIZE" -lt 1000000 ]; then
  echo "dump is only $SIZE bytes" >&2
  false
fi

aws s3 cp "$FILE" "s3://my-backups/$(basename "$FILE")"

curl -fsS -m 10 --retry 3 -o /dev/null --data-raw "size=$SIZE" "$PING"

Здесь важны детали:

Запускайте скрипт из cron в спокойную минуту, а не ровно в полночь, и пишите лог:

17 3 * * * /usr/local/bin/backup.sh >> /var/log/backup.log 2>&1

Настройте проверку

  1. Создайте проверку с cron-расписанием 17 3 * * * и часовым поясом сервера.
  2. Задайте запас времени больше обычной длительности. Если бэкап идёт 20 минут, разумно поставить 45–60 минут. Скрипт шлёт /start, поэтому запуск, который начался, но не закончился за это время, будет отмечен как зависший.
  3. Выберите, куда приходят алерты: Telegram, Slack, Discord, почта или вебхук.
  4. Подставьте адрес проверки в переменную PING.

MySQL и MariaDB

Меняется только строка дампа. --single-transaction снимает согласованный снимок таблиц InnoDB без блокировок, а --quick выгружает большие таблицы потоком, не загружая их в память:

mysqldump --single-transaction --quick app | gzip > "$FILE"

Храните пароль в ~/.my.cnf с правами 600, а не в командной строке, где его видят другие пользователи в списке процессов.

Проверьте алерты один раз

Мониторьте и восстановление

Успешный бэкап значит лишь то, что файл записан. Раз в месяц восстанавливайте свежий дамп во временную базу и выполняйте проверочный запрос, например считайте строки в таблице, которая никогда не бывает пустой. Сделайте это задачей по расписанию со своей проверкой — тогда вы будете знать, что бэкапы действительно рабочие.

Другие руководства