Skip to main content

Система валидации SQL-бекапов

Обзор

Автоматическая система проверки целостности бекапов базы данных. Когда разработчик размещает SQL-дамп на сервере UZ-2, система автоматически отправляет его на UZ-3 для валидации, после чего результаты проверки уходят в мониторинг.

Зачем это нужно

  • Раннее обнаружение проблем — узнаём о битом бекапе сразу, а не когда понадобится восстановление
  • Автоматизация — не нужно вручную проверять каждый дамп
  • История в мониторинге — видно когда и какие бекапы проходили проверку

Архитектура

Серверы

СерверРольIP
UZ-2Реплика, источник дампов172.16.10.20
UZ-3Валидатор бекапов172.18.10.11
ОфисInfluxDB + Grafana172.20.109.253

Между UZ-2 и UZ-3 прямая сетевая связанность. Между UZ-3 и офисом — IPSec туннель.

Процесс валидации

Компоненты

UZ-2: Watcher

Служба на основе inotifywait, которая следит за папкой с дампами. Когда появляется новый .sql файл:

  1. Ждёт завершения записи файла
  2. Отправляет файл на UZ-3 через rsync
  3. Дёргает webhook для запуска валидации

Расположение: ~/backup-watcher.sh

Отслеживаемая папка: /home/forge

UZ-3: Webhook Server

Минималистичный HTTP-сервер на bash + netcat. Слушает порт 8080 и при получении POST-запроса запускает скрипт валидации.

Расположение: ~/backup-validator/webhook-server.sh

Порт: 8080

UZ-3: Validator

Основной скрипт валидации. Выполняет:

  1. Поднимает чистый MySQL-контейнер
  2. Импортирует SQL-дамп
  3. Проверяет что таблицы создались
  4. Считает checksum каждой таблицы
  5. Отправляет метрики в InfluxDB
  6. Перемещает файл в verified или failed
  7. Удаляет контейнер и volume

Расположение: ~/backup-validator/validator.sh

UZ-3: Структура директорий

~/backup-validator/
├── config.env # Настройки (InfluxDB, пароли)
├── docker-compose.yml # Конфигурация MySQL
├── validator.sh # Скрипт валидации
├── webhook-server.sh # HTTP-сервер
├── logs/
│ └── backup-validator.log
└── backups/
├── incoming/ # Входящие бекапы
├── verified/ # Успешно проверенные
└── failed/ # С ошибками

Что проверяется

ПроверкаОписание
ИмпортДамп успешно загружается в MySQL без ошибок
ТаблицыПосле импорта в базе есть таблицы
ChecksumУ каждой таблицы валидный checksum (не NULL)

Метрики

В InfluxDB отправляются следующие данные:

Measurement: backup_validation

Tags:

  • db — имя базы
  • file — имя файла
  • status — success / failed

Fields:

  • duration — время валидации в секундах
  • tables — количество таблиц

Пример запроса для Grafana

from(bucket: "backupserver")
|> range(start: -7d)
|> filter(fn: (r) => r._measurement == "backup_validation")
|> filter(fn: (r) => r.status == "failed")

Алерты

Рекомендуемые алерты в Grafana:

  1. Бекап не прошёлstatus=failed
  2. Бекап не приходил 25+ часов — отсутствие метрики

Управление

Запуск служб

UZ-2 (Watcher):

nohup ~/backup-watcher.sh > ~/watcher.log 2>&1 &

UZ-3 (Webhook):

nohup ~/backup-validator/webhook-server.sh > ~/logs/webhook.log 2>&1 &

Проверка статуса

# UZ-3: Webhook работает?
curl http://localhost:8080/health

# UZ-3: Последние логи
tail -f ~/backup-validator/logs/backup-validator.log

Ручной запуск валидации

# Положить файл и запустить
cp backup.sql ~/backup-validator/backups/incoming/
~/backup-validator/validator.sh

Перезапуск служб

# UZ-2
pkill -f backup-watcher
nohup ~/backup-watcher.sh > ~/watcher.log 2>&1 &

# UZ-3
pkill -f webhook-server
nohup ~/backup-validator/webhook-server.sh > ~/backup-validator/logs/webhook.log 2>&1 &

Troubleshooting

Webhook не отвечает

# Проверить что процесс запущен
ps aux | grep webhook

# Проверить что порт слушается
ss -tlnp | grep 8080

# Перезапустить
pkill -f webhook-server
nohup ~/backup-validator/webhook-server.sh > ~/logs/webhook.log 2>&1 &

Валидация падает

# Запустить вручную с дебагом
cd ~/backup-validator
bash -x validator.sh 2>&1 | tee debug.log

MySQL контейнер не стартует

# Проверить Docker
docker ps -a
docker logs mysql-validator

# Очистить и попробовать снова
docker-compose down -v
docker volume rm backup-validator_mysql_data

Файлы не приходят с UZ-2

# На UZ-2: проверить watcher
ps aux | grep watcher
tail -f ~/watcher.log

# Проверить rsync вручную
rsync -avz test.sql user@UZ-3-IP:/home/ubuntu/backup-validator/backups/incoming/

Безопасность

  • SSH-ключи для rsync между UZ-2 и UZ-3
  • Webhook доступен только из внутренней сети
  • MySQL-контейнер не имеет проброшенных портов наружу
  • InfluxDB токен хранится в config.env (не в git)