Данные — это самое ценное, что есть у проекта. Серверы можно переустановить, код — восстановить из Git, но потерянная база данных с заказами, пользователями и транзакциями может означать конец бизнеса. По статистике, большинство компаний, потерявших критически важные данные и не имевших бэкапов, закрываются в течение года.
Резервное копирование — это не просто «скопировать файлы куда-нибудь». Это целая дисциплина, которая включает стратегию, инструменты, автоматизацию, шифрование и, самое главное, регулярную проверку восстановления.
В этой статье мы подробно разберём:
- Зачем нужны бэкапы и какие угрозы они закрывают.
- Правило 3-2-1 и другие стратегии.
- Типы бэкапов: полные, инкрементные, дифференциальные.
- Инструменты: rsync, tar, mysqldump, pg_dump.
- Продвинутые инструменты: BorgBackup, Restic, Duplicity.
- Бэкап баз данных MySQL и PostgreSQL.
- Хранение в облаке: S3, Backblaze B2, Wasabi.
- Шифрование бэкапов.
- Автоматизацию через cron и systemd timers.
- Верификацию и тестирование восстановления.
- Частые ошибки и лучшие практики.
1. Зачем нужны бэкапы
Бэкапы защищают от множества угроз:
| Угроза | Последствия | Как спасает бэкап |
|---|---|---|
| Аппаратный сбой | Выход из строя диска, сервера | Восстановление на новом сервере |
| Человеческий фактор | Случайное удаление файлов, rm -rf | Откат к предыдущей версии |
| Взлом и шифровальщики | Данные зашифрованы, требуют выкуп | Восстановление из чистой копии |
| Ошибка в коде | Массовое удаление или порча данных | Откат к состоянию до обновления |
| Стихийное бедствие | Пожар, наводнение, отключение питания | Восстановление из удалённой копии |
| Ошибка обновления | Новая версия ПО ломает БД | Откат к предыдущей версии |
Ключевая мысль: бэкап бесполезен, если его нельзя восстановить. Поэтому главный критерий — не наличие бэкапа, а возможность восстановления.
2. Стратегии резервного копирования
2.1 Правило 3-2-1
Классическая стратегия, которую рекомендуют все специалисты по данным:
- 3 копии данных (основная + две резервные).
- 2 разных носителя (например, локальный диск и облако).
- 1 копия вне офиса (удалённое хранилище, другой город).
Пример:
- Основные данные — на сервере.
- Локальный бэкап — на отдельном диске на том же сервере.
- Удалённый бэкап — в облаке (S3, Backblaze B2).
2.2 Правило 3-2-1-1-0
Расширенная версия:
- 3 копии.
- 2 разных носителя.
- 1 копия вне офиса.
- 1 копия offline (не подключена к сети, защита от шифровальщиков).
- 0 ошибок при проверке восстановления.
2.3 RPO и RTO
- RPO (Recovery Point Objective) — сколько данных вы готовы потерять. Если RPO = 1 час, бэкапы должны делаться каждый час.
- RTO (Recovery Time Objective) — как быстро вы должны восстановиться. Если RTO = 30 минут, нужна горячая реплика.
Эти параметры определяют частоту бэкапов и выбор инструментов.
2.4 Каскадная стратегия (дедовский метод)
- Ежедневные бэкапы — хранятся 7 дней.
- Еженедельные — хранятся 4 недели.
- Ежемесячные — хранятся 12 месяцев.
- Ежегодные — хранятся несколько лет.
Это позволяет экономить место, сохраняя долгосрочную историю.
3. Типы бэкапов
| Тип | Описание | Плюсы | Минусы |
|---|---|---|---|
| Полный (Full) | Копия всех данных | Простое восстановление | Много места, долго |
| Инкрементный (Incremental) | Только изменения с последнего бэкапа (любого типа) | Быстро, мало места | Восстановление требует всей цепочки |
| Дифференциальный (Differential) | Изменения с последнего полного бэкапа | Быстрее восстановление, чем инкремент | Больше места, чем инкремент |
| Синхронизация (Mirror) | Точная копия, изменения применяются сразу | Актуальность | Если удалили файл — он удалится и в бэкапе |
Рекомендация: комбинируйте полные и инкрементные бэкапы. Например, полный раз в неделю, инкрементный — каждый день.
4. Базовые инструменты
4.1 tar — архивация файлов
# Создание архива
tar -czf backup_$(date +%Y%m%d).tar.gz /var/www/html
# Распаковка
tar -xzf backup_20240310.tar.gz -C /restore/
# Исключение директорий
tar -czf backup.tar.gz --exclude='/var/www/html/cache' --exclude='*.log' /var/www/htmlПлюсы: простота, встроен в Linux.
Минусы: нет инкрементности, каждый раз полный архив.
4.2 rsync — синхронизация файлов
# Локальная синхронизация
rsync -av --delete /var/www/html/ /backup/html/
# Синхронизация с удалённым сервером
rsync -avz -e ssh /var/www/html/ user@backup-server:/backup/html/
# Инкрементная синхронизация с использованием hard links (экономия места)
rsync -av --link-dest=/backup/html/last /var/www/html/ /backup/html/$(date +%Y%m%d)/Ключи:
-a— архивный режим (сохраняет права, владельцев, время).-v— подробный вывод.-z— сжатие при передаче.--delete— удалять файлы в приёмнике, которых нет в источнике.--link-dest— создавать жёсткие ссылки на неизменённые файлы (экономия места).
Плюсы: эффективная синхронизация, работа по SSH.
Минусы: не хранит историю версий (если без --link-dest).
4.3 mysqldump — бэкап MySQL
# Дамп одной базы
mysqldump -u root -p mydb > mydb_$(date +%Y%m%d).sql
# Дамп всех баз
mysqldump -u root -p --all-databases > all_dbs_$(date +%Y%m%d).sql
# Сжатие на лету
mysqldump -u root -p mydb | gzip > mydb_$(date +%Y%m%d).sql.gz
# Согласованный дамп без блокировки таблиц (InnoDB)
mysqldump -u root -p --single-transaction mydb > mydb.sqlВосстановление:
mysql -u root -p mydb < mydb_20240310.sql
# или
gunzip < mydb_20240310.sql.gz | mysql -u root -p mydb4.4 pg_dump — бэкап PostgreSQL
# Дамп одной базы
pg_dump -U postgres mydb > mydb_$(date +%Y%m%d).sql
# Дамп в кастомном формате (сжатие, параллельное восстановление)
pg_dump -U postgres -Fc mydb > mydb_$(date +%Y%m%d).dump
# Дамп всех баз
pg_dumpall -U postgres > all_dbs_$(date +%Y%m%d).sqlВосстановление:
psql -U postgres mydb < mydb_20240310.sql
# или для кастомного формата
pg_restore -U postgres -d mydb mydb_20240310.dump5. Продвинутые инструменты
5.1 BorgBackup
Borg — мощный инструмент с дедупликацией, сжатием и шифрованием.
Установка:
sudo apt install borgbackupИнициализация репозитория:
borg init --encryption=repokey /backup/borgСоздание бэкапа:
borg create /backup/borg::'{now:%Y-%m-%d_%H:%M}' /var/www/html /etc/nginxПросмотр архивов:
borg list /backup/borgВосстановление:
borg extract /backup/borg::2024-03-10_12:00Плюсы: дедупликация (экономия места), шифрование, сжатие, инкрементность.
Минусы: требует изучения, репозиторий нельзя просто скопировать (нужен экспорт).
5.2 Restic
Restic — современный инструмент с поддержкой облаков (S3, Backblaze B2, Wasabi).
Установка:
sudo apt install resticИнициализация:
restic init --repo s3:s3.amazonaws.com/my-bucketСоздание бэкапа:
restic -r s3:s3.amazonaws.com/my-bucket backup /var/www/htmlВосстановление:
restic -r s3:s3.amazonaws.com/my-bucket restore latest --target /restoreПлюсы: поддержка облаков, шифрование, дедупликация, простота.
Минусы: требует настройки доступа к облаку.
5.3 Duplicity
Duplicity — инструмент с шифрованием и поддержкой облаков.
Установка:
sudo apt install duplicityСоздание бэкапа:
duplicity /var/www/html s3://s3.amazonaws.com/my-bucketВосстановление:
duplicity restore s3://s3.amazonaws.com/my-bucket /restoreПлюсы: шифрование, инкрементность, облака.
Минусы: сложнее в настройке, чем Restic.
5.4 Сравнение инструментов
| Инструмент | Дедупликация | Шифрование | Облака | Сложность |
|---|---|---|---|---|
| tar | Нет | Нет | Нет | Низкая |
| rsync | Частичная экономия места через жёсткие ссылки (hard links) — не дедупликация в полном смысле | Нет | Через SSH | Низкая |
| Borg | Да | Да | Нет (только SSH) | Средняя |
| Restic | Да | Да | Да | Средняя |
| Duplicity | Нет | Да | Да | Средняя |
6. Бэкап баз данных
6.1 MySQL / MariaDB
Логический бэкап (mysqldump):
mysqldump -u root -p --single-transaction --routines --triggers --events mydb | gzip > mydb_$(date +%Y%m%d).sql.gzФизический бэкап (Percona XtraBackup):
xtrabackup --backup --target-dir=/backup/mysql/
xtrabackup --prepare --target-dir=/backup/mysql/Плюсы физического: быстрее, не блокирует БД.
Минусы: требует установки, сложнее.
6.2 PostgreSQL
Логический бэкап (pg_dump):
pg_dump -U postgres -Fc mydb > mydb_$(date +%Y%m%d).dumpФизический бэкап (pg_basebackup):
pg_basebackup -U replicator -D /backup/postgresql/ -P -vНепрерывное архивирование (WAL):
Настройте archive_mode = on и archive_command для копирования WAL-логов. Это позволяет восстановиться на любой момент времени (Point-in-Time Recovery).
6.3 Репликация как часть стратегии
Репликация — это не бэкап, но она дополняет его:
- Master-slave — если мастер падает, слейв можно повысить.
- Задержка репликации — можно настроить слейв с задержкой на час, чтобы защититься от случайного удаления данных.
Важно: репликация не защищает от DROP TABLE — команда мгновенно применится на слейве. Репликация не спасает от логических ошибок (DROP DATABASE, UPDATE без WHERE). Для этого нужны point-in-time recovery (WAL-архивы, binlog) или снапшоты.
7. Хранение в облаке
Облако — это «1» из правила 3-2-1 (копия вне офиса).
7.1 AWS S3
# Загрузка файла
aws s3 cp backup.tar.gz s3://my-bucket/backups/
# Синхронизация директории
aws s3 sync /backup/ s3://my-bucket/backups/Настройка lifecycle: автоматическое удаление старых бэкапов через N дней.
7.2 Backblaze B2
Дешевле S3, совместим с S3 API.
b2 upload-file my-bucket backup.tar.gz backups/backup.tar.gz7.3 Wasabi
Ещё один дешёвый провайдер, совместимый с S3.
aws s3 cp backup.tar.gz s3://my-bucket/ --endpoint-url=https://s3.wasabisys.com7.4 Сравнение облаков
| Провайдер | Цена за ГБ | Особенности |
|---|---|---|
| AWS S3 | ~$0.023 | Много сервисов, сложный биллинг |
| Backblaze B2 | ~$0.005 | Дешёвый, простой |
| Wasabi | ~$0.0059 | Нет платы за трафик |
8. Шифрование бэкапов
Если бэкап содержит конфиденциальные данные, его нужно шифровать.
8.1 GPG
# Шифрование
gpg --symmetric --cipher-algo AES256 backup.tar.gz
# Расшифровка
gpg --decrypt backup.tar.gz.gpg > backup.tar.gz8.2 openssl
# Шифрование
openssl enc -aes-256-cbc -salt -in backup.tar.gz -out backup.tar.gz.enc
# Расшифровка
openssl enc -d -aes-256-cbc -in backup.tar.gz.enc -out backup.tar.gz8.3 Встроенное шифрование Borg/Restic
Borg и Restic шифруют данные автоматически при создании репозитория. Это самый удобный способ.
9. Автоматизация бэкапов
9.1 Скрипт бэкапа с ротацией
#!/bin/bash
# backup.sh
set -euo pipefail
BACKUP_DIR="/backups"
DATE=$(date +%Y%m%d_%H%M%S)
WEB_ROOT="/var/www/html"
DB_NAME="mydb"
DB_USER="${DB_USER:-root}"
DB_PASS="${DB_PASS:-$(cat /etc/backup/db_pass 2>/dev/null)}"
RETENTION_DAYS=7
if [ -z "$DB_PASS" ]; then
echo "ОШИБКА: Пароль БД не найден. Укажите DB_PASS или создайте /etc/backup/db_pass" >&2
exit 1
fi
# Создание директории
mkdir -p "$BACKUP_DIR"
# Бэкап файлов
tar -czf "$BACKUP_DIR/files_$DATE.tar.gz" "$WEB_ROOT"
# Бэкап базы данных
mysqldump -u "$DB_USER" -p"$DB_PASS" --single-transaction "$DB_NAME" | gzip > "$BACKUP_DIR/db_$DATE.sql.gz"
# Шифрование
gpg --symmetric --cipher-algo AES256 --batch --passphrase-file /etc/backup.key "$BACKUP_DIR/files_$DATE.tar.gz"
gpg --symmetric --cipher-algo AES256 --batch --passphrase-file /etc/backup.key "$BACKUP_DIR/db_$DATE.sql.gz"
# Удаление незашифрованных файлов
rm "$BACKUP_DIR/files_$DATE.tar.gz" "$BACKUP_DIR/db_$DATE.sql.gz"
# Загрузка в облако
aws s3 cp "$BACKUP_DIR/files_$DATE.tar.gz.gpg" s3://my-bucket/backups/
aws s3 cp "$BACKUP_DIR/db_$DATE.sql.gz.gpg" s3://my-bucket/backups/
# Удаление старых бэкапов
find "$BACKUP_DIR" -name "*.gpg" -mtime +"$RETENTION_DAYS" -delete
echo "Бэкап завершён: $DATE"
ВАЖНО! Никогда не храните пароли в скриптах. Файл с паролем должен храниться отдельно от бэкапов, иметь права 600 и быть недоступным для обычных пользователей. Ещё лучше — использовать аппаратные модули или секретные хранилища
9.2 Cron
# Редактирование crontab
crontab -e
# Запуск каждый день в 2:00
0 2 * * * /usr/local/bin/backup.sh >> /var/log/backup.log 2>&1
# Запуск каждый час (для критичных данных)
0 * * * * /usr/local/bin/backup.sh >> /var/log/backup.log 2>&19.3 Systemd timers
Альтернатива cron с более гибкими настройками.
/etc/systemd/system/backup.service:
ini
[Unit]
Description=Backup Service
[Service]
Type=oneshot
ExecStart=/usr/local/bin/backup.sh
User=root/etc/systemd/system/backup.timer:
ini
[Unit]
Description=Run backup daily
[Timer]
OnCalendar=daily
Persistent=true
[Install]
WantedBy=timers.targetВключение:
sudo systemctl enable backup.timer
sudo systemctl start backup.timer9.4 Мониторинг бэкапов
Настройте уведомления об успехе/неудаче.
# В конце скрипта
if [ $? -eq 0 ]; then
echo "Backup successful" | mail -s "Backup OK" admin@example.com
else
echo "Backup FAILED" | mail -s "Backup FAILED" admin@example.com
fiИли отправляйте в Telegram через бота. Современные способы уведомлений:
curl -s -X POST "https://api.telegram.org/bot${TELEGRAM_BOT_TOKEN}/sendMessage" \
-d chat_id="${TELEGRAM_CHAT_ID}" \
-d text="Backup ${STATUS}: $(date)"10. Верификация и тестирование восстановления
Это самый важный раздел. Бэкап, который не проверен, — это не бэкап.
10.1 Проверка целостности
Для tar:
tar -tzf backup.tar.gz > /dev/null && echo "OK"Для Borg:
borg check /backup/borgДля Restic:
restic -r s3:s3.amazonaws.com/my-bucket check10.2 Тестовое восстановление
Регулярно (раз в месяц) восстанавливайте бэкап на тестовом сервере и проверяйте, что данные на месте.
Пример для MySQL:
# Восстановление на тестовом сервере
gunzip < db_20240310.sql.gz | mysql -u root -p test_mydb
# Проверка количества записей
mysql -u root -p -e "SELECT COUNT(*) FROM test_mydb.users;"Ещё один уровень проверки: проверка схемы и индексов. Например, после восстановления можно сделать:
mysql -u root -p -e "SHOW CREATE TABLE test_mydb.users;"10.3 Автоматическая проверка
Добавьте в скрипт бэкапа проверку:
# Проверка, что бэкап не пустой
if [ ! -s "$BACKUP_DIR/db_$DATE.sql.gz" ]; then
echo "Backup file is empty!" | mail -s "Backup FAILED" admin@example.com
exit 1
fi
# Проверка, что архив открывается для небольших архивов.
tar -tzf "$BACKUP_DIR/files_$DATE.tar.gz" > /dev/null
# Если архив большой, лучше проверять только наличие заголовка или первые N файлов
tar -tf "$BACKUP_DIR/files_$DATE.tar.gz" | head -n 5 > /dev/null 2>&1
if [ $? -ne 0 ]; then
echo "Backup archive is corrupted!" | mail -s "Backup FAILED" admin@example.com
exit 1
fi11. Частые ошибки и лучшие практики
| Ошибка | Последствия | Решение |
|---|---|---|
| Бэкапы не делаются | Потеря данных | Автоматизируйте через cron. |
| Бэкапы делаются, но не проверяются | При восстановлении выясняется, что архив битый | Регулярно тестируйте восстановление. |
| Бэкапы хранятся только на том же сервере | При отказе сервера теряются и данные, и бэкапы | Используйте удалённое хранилище (правило 3-2-1). |
| Бэкапы не шифруются | Утечка конфиденциальных данных | Шифруйте (GPG, Borg, Restic). |
Бэкап делается без --single-transaction | Блокировка таблиц, неконсистентные данные | Используйте --single-transaction для InnoDB. |
| Нет ротации | Диск переполняется | Настройте удаление старых бэкапов. |
| Бэкапы хранятся вечно | Растущие расходы на облако | Настройте lifecycle policy. |
| Нет мониторинга | Бэкап упал, никто не заметил | Настройте уведомления. |
| Восстановление не документировано | Паника при сбое | Напишите инструкцию по восстановлению. |
| Бэкап только раз в день | Потеря данных за день | Увеличьте частоту для критичных данных. |
ВАЖНО! —single-transaction гарантирует консистентность только для транзакционных движков (InnoDB, NDB). Для MyISAM используйте другие методы или мигрируйте на InnoDB
Лучшие практики:
- Автоматизируйте. Ручные бэкапы забываются.
- Проверяйте. Регулярно восстанавливайте на тестовом сервере.
- Шифруйте. Особенно если храните в облаке.
- Ротируйте. Храните ежедневные, еженедельные, ежемесячные копии.
- Документируйте. Напишите инструкцию, как восстановить данные.
- Мониторьте. Узнавайте о проблемах до того, как они станут критичными.
- Тестируйте сценарии. Что если диск умер? Что если сервер украли? Что если база повреждена?
Помните: бэкап — это не тот, который делается, а тот, который восстанавливается. Регулярно проверяйте свои бэкапы, и вы сможете спать спокойно, зная, что данные в безопасности.
