Налаштування автоматичного бекапування бази даних за розписанням
Втрата даних через відсутність резервних копій — одна з найдорожчаших помилок у експлуатації веб-програм. Налаштування автоматичних планових резервних копій — базова вимога для будь-якого production-сервера.
Вибір інструменту
| БД | Інструмент | Формат |
|---|---|---|
| PostgreSQL | pg_dump / pg_dumpall |
SQL / custom |
| MySQL/MariaDB | mysqldump / Percona XtraBackup |
SQL / binary |
| MongoDB | mongodump |
BSON |
| Redis | BGSAVE / AOF snapshot |
RDB / AOF |
| SQLite | sqlite3 .backup |
binary |
PostgreSQL: базова настройка
#!/bin/bash
# /opt/scripts/backup-postgres.sh
BACKUP_DIR="/var/backups/postgres"
DB_NAME="myapp_production"
DATE=$(date +%Y%m%d_%H%M%S)
FILENAME="$BACKUP_DIR/${DB_NAME}_${DATE}.dump"
mkdir -p "$BACKUP_DIR"
pg_dump -U postgres -Fc "$DB_NAME" > "$FILENAME"
# Видалення резервних копій старше 7 днів
find "$BACKUP_DIR" -name "*.dump" -mtime +7 -delete
# Перевірка успішності
if [ $? -eq 0 ]; then
echo "Backup successful: $FILENAME"
else
echo "Backup FAILED" >&2
exit 1
fi
Cron-завдання:
0 2 * * * /opt/scripts/backup-postgres.sh >> /var/log/backup.log 2>&1
MySQL: налаштування з паролем через .my.cnf
# ~/.my.cnf (дозволи 600)
[mysqldump]
user=backup_user
password=secret_password
mysqldump --single-transaction --routines --triggers myapp_db | \
gzip > "/var/backups/mysql/myapp_$(date +%Y%m%d_%H%M%S).sql.gz"
--single-transaction критично важливий для InnoDB — створює консистентний снапшот без блокування таблиць.
Ротація та зберігання
Стратегія GFS (Grandfather-Father-Son):
- Щоденні — зберігаються 7 днів
- Щотижневі — зберігаються 4 тижні
- Щомісячні — зберігаються 12 місяців
Реалізація через logrotate або скрипт з find -mtime.
Завантаження в S3/об'єктне сховище
aws s3 cp "$FILENAME" "s3://company-backups/postgres/${DB_NAME}/" \
--storage-class STANDARD_IA \
--server-side-encryption AES256
# Або через rclone для будь-якого провайдера
rclone copy "$FILENAME" remote:backups/postgres/
Автоматична ротація в S3 налаштовується через Lifecycle Policy: переміщення у Glacier через 30 днів, видалення через 1 рік.
Сповіщення про помилки
# Відправити сповіщення в Slack при сбої
if [ $? -ne 0 ]; then
curl -X POST "$SLACK_WEBHOOK" \
-d '{"text": "CRITICAL: Database backup failed on '"$(hostname)"'"}'
fi
Альтернатива — healthcheck через Healthchecks.io або Better Uptime: скрипт пінгує URL після успішного бекапу, сервіс бахує тревогу якщо пінг не прийшов.
Перевірка резервних копій
Резервна копія без тестування відновлення — не резервна копія. Щотижневий тест:
# Відновлення в тестову БД
pg_restore -U postgres -d test_restore --clean "$FILENAME"
# Перевірка кількості записів
psql -U postgres -d test_restore -c "SELECT COUNT(*) FROM users;"
Тривалість
Налаштування бекапування однієї БД з ротацією та S3-завантаженням — 1 робочий день.







