Как правильно делать бэкапы: аудит, мониторинг и проверка восстановления
Ниже — не теория про 3-2-1, а практический порядок проверки: что именно копируется, где лежат копии, насколько они свежие, защищены ли от удаления и можно ли из них реально восстановиться.
1. Составляем реестр систем
cat > /root/backup-inventory.csv <<'EOF'
system,data,RPO,RTO,backup_method,repository,retention,restore_test
web01,/var/www + database,24h,4h,rsync+mysqldump,backup01,14 daily,monthly
postgres01,all databases,1h,2h,pgBackRest,repo02,7 daily + 4 weekly,monthly
vmhost01,critical VMs,24h,8h,Veeam,NAS+offsite,14 daily,quarterly
EOF
column -s, -t /root/backup-inventory.csvДля каждой системы должны быть указаны данные, RPO, RTO, метод, место хранения, retention и дата последнего restore-test.
2. Проверяем свежесть локальных копий
find /var/backups -xdev -type f -printf '%T@ %TY-%Tm-%Td %TH:%TM %s %p\n' | sort -n | tail -20
find /var/backups -xdev -type f -mtime -1 -ls
du -sh /var/backups
df -h /var/backups
df -i /var/backupsОтсутствие свежих файлов, резкое падение размера или заполненный repository должны давать alert.
3. Проверяем, что источник действительно существует
findmnt
lsblk -f
systemctl --failed
mountpoint /srv/data
mountpoint /var/lib/postgresqlОчень маленький «успешный» backup часто означает, что source mount не был подключён.
4. Проверяем копии по схеме 3-2-1-1-0
- production-данные;
- основной backup repository;
- offsite-копия;
- immutable/offline-копия;
- 0 ошибок после проверки и restore-test.
Для offsite-хранилища выполните отдельную проверку доступности и свежести:
ssh backup@offsite01 'hostname; df -h /backup; find /backup -type f -mtime -2 | tail -20'5. Проверяем целостность архивов
find /var/backups -type f -name '*.gz' -exec gzip -t {} \;
find /var/backups -type f -name '*.xz' -exec xz -t {} \;
find /var/backups -type f -name '*.tar.gz' -exec tar -tzf {} \; >/dev/nullДля крупных наборов используйте выборочную или фоновую проверку, чтобы не перегружать storage.
6. Добавляем checksum-manifest
cd /var/backups
find . -type f ! -name SHA256SUMS -print0 | sort -z | xargs -0 sha256sum > SHA256SUMS
sha256sum -c SHA256SUMSChecksum не заменяет restore-test, но помогает обнаружить повреждение файлов.
7. Создаём единый freshness-check
cat > /usr/local/sbin/check-backup-age.sh <<'EOF'
#!/usr/bin/env bash
set -Eeuo pipefail
DIR=${1:-/var/backups}
MAX_HOURS=${2:-26}
LATEST=$(find "$DIR" -type f -printf '%T@\n' | sort -nr | head -1)
[ -n "$LATEST" ] || { echo "CRIT: no backup files"; exit 2; }
NOW=$(date +%s)
AGE=$(( (NOW - ${LATEST%.*}) / 3600 ))
if (( AGE > MAX_HOURS )); then
echo "CRIT: newest backup is ${AGE}h old"
exit 2
fi
echo "OK: newest backup is ${AGE}h old"
EOF
chmod 750 /usr/local/sbin/check-backup-age.sh
/usr/local/sbin/check-backup-age.sh /var/backups 268. Проверяем размер относительно обычного диапазона
du -sb /var/backups
find /var/backups -maxdepth 1 -type f -printf '%TY-%Tm-%Td %s %f\n' | sortВ мониторинге полезно сравнивать размер с медианой последних успешных запусков и сигнализировать при отклонении, например, более чем на 50%.
9. Выполняем file-level restore-test
install -d -m 700 /root/restore-test
cp -a /var/backups/config-latest.tar.gz /root/restore-test/
tar -xzf /root/restore-test/config-latest.tar.gz -C /root/restore-test/
find /root/restore-test -maxdepth 3 -type f | head
sha256sum /root/restore-test/config-latest.tar.gz10. Выполняем restore-test базы
Для SQL-копии восстанавливайте её в отдельную тестовую базу или контейнер. Пример MySQL:
docker run --rm --name backup-restore-mysql \
-e MYSQL_ROOT_PASSWORD=testpass \
-p 127.0.0.1:3307:3306 -d mysql:8
until mysql -h127.0.0.1 -P3307 -uroot -ptestpass -e 'SELECT 1'; do sleep 2; done
gzip -dc /var/backups/mysql/app-latest.sql.gz | mysql -h127.0.0.1 -P3307 -uroot -ptestpass
mysql -h127.0.0.1 -P3307 -uroot -ptestpass -e 'SHOW DATABASES;'
docker stop backup-restore-mysql11. Фиксируем результат восстановления
install -d -m 700 /var/lib/backup-audit
printf '%s system=web01 result=success duration=18m operator=%s\n' \
"$(date -Is)" "$(id -un)" >> /var/lib/backup-audit/restore-tests.log
tail -20 /var/lib/backup-audit/restore-tests.log12. Минимальные алерты
- последняя успешная копия старше RPO;
- repository заполнен более чем на 85%;
- размер отклонился от baseline;
- архив или checksum не прошёл проверку;
- offsite-копия не обновлялась;
- restore-test просрочен.
13. Критерий успеха
Backup-система считается рабочей, когда для каждой критичной системы есть актуальная копия в пределах RPO, offsite/immutable-экземпляр, repository не переполнен, автоматические проверки проходят, а тестовое восстановление укладывается в RTO и записано в журнал.