15. Бэкапы и восстановление

1. Что вообще такое бэкапы и зачем они нужны

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

В мире реляционных и NoSQL баз данных резервное копирование (бэкап) — это тот самый непотопляемый тубус. Это сохраненная на независимом носителе копия данных, предназначенная для гарантированного восстановления системы после катастрофических событий: аппаратного сбоя накопителей, случайного DROP DATABASE от усталого администратора, повреждения файловой системы, программного бага в миграциях или атаки вирусов-вымогателей (ransomware).

Фундаментальные цели создания бэкапов:

  • Обеспечить гарантированную возможность восстановления (Restore) в заданные сроки;
  • Минимизировать потерю данных: показатель RPO (Recovery Point Objective);
  • Минимизировать время простоя бизнеса: показатель RTO (Recovery Time Objective);
  • Удовлетворять требованиям регуляторов и аудита: законы о защите персональных данных, банковские стандарты безопасности (PCI-DSS, GDPR, SOX).

2. Основные термины: RPO, RTO, частота backup-ов

При проектировании стратегии аварийного восстановления инженер оперирует двумя главными метриками:

  • RPO (Recovery Point Objective) — целевая точка восстановления. Это максимальный временной интервал данных, который бизнес готов безвозвратно потерять при катастрофе:
    • Суточный ночной бэкап (nightly backup) $\rightarrow$ RPO ≈ 24 часа (в худшем случае теряется весь рабочий день);
    • Регулярная непрерывная архивация WAL/binlog $\rightarrow$ RPO сокращается до секунд или долей минут.
  • RTO (Recovery Time Objective) — целевое время восстановления. Это максимальное время, в течение которого сервис может оставаться недоступным для пользователей, пока инженеры поднимают базу:
    • Зависит от размера базы данных, скорости чтения с хранилища бэкапов (S3/SAN), пропускной способности сети, производительности дисков и сложности наката журналов.
  • Частота backup-ов выбирается на основе математического баланса между допустимым RPO и влиянием процесса резервирования на CPU и I/O боевого сервера: чем чаще создается снимок, тем меньше RPO, но выше нагрузка на накопители и сеть.

3. Виды backup-ов (логические / физические, полные / инкрементальные и т.п.)

3.1 Логический vs физический бэкап

Существует два принципиально разных подхода к извлечению данных из СУБД:

  • Логический бэкап — выгрузка структуры и данных в виде декларативных текстовых SQL-инструкций (CREATE TABLE, INSERT) или платформонезависимого бинарного формата:

    • PostgreSQL: pg_dump, pg_dumpall;
    • MySQL: mysqldump, mysqlpump;
    • SQL Server: экспорт пакетов BACPAC/DACFx.
    • Плюсы: Полная переносимость между версиями СУБД, архитектурами процессоров и операционными системами; легкая читаемость; возможность выборочного восстановления одной таблицы или схемы.
    • Минусы: Крайне медленная скорость снятия и катастрофически долгое восстановление на больших объемах (гигабайты парсятся и вставляются через SQL-движок); сам по себе не обеспечивает восстановления на произвольный момент времени (PITR).
  • Физический бэкап — точная побайтовая копия файлов данных на уровне файловой системы или блочного хранилища:

    • PostgreSQL: базовый бэкап (base backup через pg_basebackup) + архив WAL-сегментов (Barman, pgBackRest);
    • MySQL: прямое копирование datadir на остановленном сервере или горячий снимок без остановки через Percona XtraBackup или MySQL Enterprise Backup;
    • SQL Server: команда BACKUP DATABASE в бинарные файлы резервных копий и бэкапы файловых групп.
    • Плюсы: Максимальная скорость развертывания (скорость ограничена только пропускной способностью SSD и шины передачи данных); нативная поддержка PITR через воспроизведение журналов предзаписи.
    • Минусы: Жесткая привязка к мажорной версии СУБД, архитектуре CPU и ОС; невозможность восстановить отдельную таблицу без развертывания всего экземпляра.

3.2 Полный, дифференциальный, инкрементальный, лог-бэкапы

В промышленной эксплуатации бэкапы организуются в иерархические цепочки:

  • Full backup (полный бэкап):

    • Копия всей базы данных (всех страниц данных и метаданных) на конкретный момент времени.
    • Является абсолютной точкой отсчета для любых инкрементальных схем.
    • Требует максимального дискового пространства и времени на создание, но гарантирует простейшее и надежнейшее восстановление.
  • Differential backup (дифференциальный бэкап):

    • Сохраняет только те страницы и блоки данных, которые изменились с момента последнего полного бэкапа.
    • Схема восстановления: восстанавливается базовый полный бэкап + ровно один последний дифференциальный снимок.
    • Баланс между временем создания и скоростью восстановления: быстрее, чем полный, а цепочка восстановления состоит всего из двух звеньев.
  • Incremental backup (инкрементальный бэкап):

    • Сохраняет только изменения, произошедшие с момента предыдущего бэкапа любого типа (будь то полный или предыдущий инкрементальный).
    • Схема восстановления: базовый полный бэкап + последовательное применение всех инкрементов по цепочке без единого пропуска.
    • Минимальный размер файлов и минимальная нагрузка на сеть, но восстановление дольше и уязвимо к повреждению любого промежуточного звена цепочки.
  • Transaction log backup / WAL archive (лог-бэкап):

    • Непрерывная передача в хранилище журналов транзакций (WAL в PostgreSQL, binlog в MySQL, transaction log в SQL Server).
    • Позволяет реализовать Point-in-Time Recovery (PITR): восстановить состояние базы данных на любую миллисекунду в прошлом (например, за секунду до выполнения ошибочной команды).

3.3 Сводная таблица

Тип бэкапа Что копируется Скорость backup Скорость restore Сложность схемы Типичный сценарий
Полный Все данные и метаданные Медленно Средне Низкая Базовый снимок, небольшие БД
Дифференциальный Изменения с последнего полного Средне Быстро Средняя Снижение RPO без сложных цепочек
Инкрементальный Изменения с последнего бэкапа Быстро Медленно Высокая Большие БД, терабайты данных
Лог-бэкап / WAL Журнал транзакций Очень быстро Очень быстро Средняя PITR, непрерывная защита, минимальный RPO

4. Стратегии бэкапа и соответствие RPO/RTO

4.1 Примеры стратегий

  1. Простая nightly-стратегия (для разработки и небольших сервисов):

    • Полный логический дамп раз в сутки в 03:00 ночи.
    • RPO ≈ 24 часа, RTO от десятков минут до часов в зависимости от объема.
    • Применима для некритичных внутренних систем и стейджингов.
  2. Полный + дифференциальные бэкапы:

    • Полный физический снимок в ночь на воскресенье, дифференциальные срезы — каждую ночь в будни.
    • RPO ≈ 24 часа (или меньше при частых дифференциалах), восстановление существенно быстрее ночного полного дампа.
  3. Полный + инкрементальные снимки:

    • Полный снимок в воскресенье, инкрементальные дельты — каждые 4–6 часов.
    • Экономия хранилища в разы, но цепочка восстановления требует идеальной целостности каждого инкремента.
  4. PITR-стратегия (Enterprise-стандарт):

    • Периодические полные физические бэкапы (еженедельно или ежедневно).
    • Непрерывная потоковая архивация журналов транзакций (WAL / binlog) каждые несколько минут или в реальном времени.
    • RPO составляет от нескольких секунд до минут; восстановление накатывает логи до точной временной метки.

4.2 Схема восстановления при полном + дифференциальном + лог-бэкапах

flowchart LR
    classDef process  fill:#1e293b,stroke:#38bdf8,stroke-width:1px,color:#f8fafc
    classDef success  fill:#064e3b,stroke:#34d399,stroke-width:1px,color:#f8fafc
    classDef error    fill:#7f1d1d,stroke:#f87171,stroke-width:1px,color:#f8fafc
    classDef warning  fill:#78350f,stroke:#fbbf24,stroke-width:1px,color:#f8fafc
    classDef entry    fill:#1e3a5f,stroke:#38bdf8,stroke-width:2px,color:#f8fafc
    classDef aux      fill:#334155,stroke:#64748b,stroke-width:1px,color:#f8fafc
    classDef system   fill:#312e81,stroke:#a78bfa,stroke-width:1px,color:#f8fafc
    classDef data     fill:#132d29,stroke:#2dd4bf,stroke-width:1px,color:#f8fafc
    classDef network  fill:#881337,stroke:#fb7185,stroke-width:1px,color:#f8fafc
    classDef accent   fill:#1e1b4b,stroke:#818cf8,stroke-width:1px,color:#f8fafc
  A["Сбой БД"]:::data --> B["Восстановить полный бэкап"]
  B --> C["Восстановить последний дифференциальный бэкап"]
  C --> D["Применить цепочку лог-бэкапов до нужного момента"]
  D --> E["База восстановлена на момент времени (PITR)"]
  

5. Практика: PostgreSQL

5.1 Логический бэкап (pg_dump)

Утилита pg_dump создает снимок одной базы данных, а pg_dumpall дополнительно выгружает глобальные объекты кластера (роли пользователей, права доступа и табличные пространства).

Пример выгрузки в текстовом формате SQL:

Bash
pg_dump -h localhost -U postgres -F p -f db_backup.sql mydb

Восстановление через клиент psql:

Bash
psql -h localhost -U postgres -d mydb -f db_backup.sql

Преимущество: простота скриптования и переносимость.
Недостаток: отсутствие PITR, колоссальное время блокировок и наката на терабайтных базах.

5.2 Физический бэкап и PITR: Barman, pgBackRest

  • Barman (Backup and Recovery Manager) — специализированный сервер администрирования бэкапов PostgreSQL, управляющий физическими base backup и непрерывной архивацией WAL.
  • pgBackRest — высокопроизводительное промышленное решение, поддерживающее многопоточный бэкап, сжатие на лету, дедупликацию и прямое сохранение в S3-хранилища.

Типичный алгоритм работы pgBackRest/Barman:

  1. Выполняется физический base backup на уровне блоков диска;
  2. СУБД непрерывно отправляет заполненные WAL-сегменты (archive_command или streaming replication) в резервное хранилище;
  3. При аварии оператор указывает точный таймстамп (recovery_target_time = '2026-09-14 14:30:00'), утилита восстанавливает файлы данных и накатывает транзакции ровно до этой секунды.

6. Практика: MySQL / MariaDB

6.1 Логический бэкап: mysqldump

Утилита mysqldump формирует набор SQL-выражений:

Bash
mysqldump -u root -p --single-transaction --routines --triggers --databases mydb > mydb_backup.sql

Флаг --single-transaction критически важен: он переводит сессию в уровень изоляции REPEATABLE READ и делает согласованный снимок таблиц движка InnoDB без глобальной блокировки чтения и записи всего сервера!

Восстановление:

Bash
mysql -u root -p mydb < mydb_backup.sql

6.2 Физический бэкап и PITR

  • Физический бэкап: копирование каталога datadir на остановленном MySQL либо горячее резервное копирование без простоя через Percona XtraBackup или MySQL Enterprise Backup. XtraBackup копирует страницы данных InnoDB на лету и одновременно отслеживает redo log, гарантируя целостность на момент окончания копирования.
  • Binlog backup: непрерывная архивация бинарных логов (log_bin). При восстановлении после наката физического бэкапа утилита mysqlbinlog воспроизводит события до нужной позиции:

    Bash
    mysqlbinlog --stop-datetime="2026-09-14 14:30:00" binlog.000001 binlog.000002 | mysql -u root -p
    

7. Практика: Microsoft SQL Server

7.1 Модели восстановления (recovery models)

SQL Server жестко привязывает стратегию резервирования к одной из трех моделей восстановления базы данных:

  • Simple (простая):
    Журнал транзакций автоматически усекается после контрольных точек; PITR невозможен. RPO равен моменту последнего созданного полного или дифференциального бэкапа.
  • Full (полная):
    Каждая транзакция удерживается в журнале до тех пор, пока не будет выполнен бэкап журнала (BACKUP LOG). Доступен полноценный PITR с субминутным RPO.
  • Bulk-logged (с неполным протоколированием):
    Минимизирует логирование массовых вставок (bulk insert), снижая нагрузку на лог, но сохраняет возможность лог-бэкапов при соблюдении условий.

7.2 Типичный сценарий для модели Full

  1. Периодический полный бэкап: BACKUP DATABASE mydb TO DISK = 'C:\backup\mydb_full.bak';
  2. Регулярные дифференциальные срезы: BACKUP DATABASE mydb TO DISK = 'C:\backup\mydb_diff.bak' WITH DIFFERENTIAL;
  3. Частые лог-бэкапы: BACKUP LOG mydb TO DISK = 'C:\backup\mydb_log.trn';
  4. Восстановление:
    • Восстановление полного бэкапа с опцией NORECOVERY (оставляет базу в режиме ожидания накатов);
    • Восстановление последнего дифференциального бэкапа с NORECOVERY;
    • Применение цепочки log-бэкапов до целевого момента с завершающим WITH RECOVERY (переводит БД в онлайн).

8. Общие best practices по бэкапам

  1. Формализуйте RPO и RTO для каждой критичной базы данных совместно с бизнесом и стройте технический пайплайн строго под эти цифры.
  2. Никогда не храните резервные копии на том же физическом диске или сервере, где работает продакшен. Используйте изолированные независимые хранилища (S3, удаленный NAS/SAN в другом дата-центре).
  3. Регулярно тестируйте процедуру восстановления (Restore Drills):
    • Автоматизированный стенд должен еженедельно поднимать базу из бэкапа на тестовой виртуалке, накатывать логи и прогонять базовые smoke-тесты. Бэкап, который не был протестирован восстановлением, равен отсутствию бэкапа.
  4. Составляйте пошаговые Runbook-инструкции: в момент аварии дежурный инженер находится в состоянии стресса и не должен вспоминать синтаксис флагов консольных утилит.
  5. Применяйте шифрование и строгий контроль доступа: бэкапы содержат все персональные данные и коммерческие секреты. Шифруйте архивы ключами gpg или встроенными механизмами утилит (TDE, Barman crypto).
  6. Настройте непрерывный мониторинг и алертинг: отслеживайте возраст последнего успешного бэкапа, размер архивов и лаг архивации WAL.
  7. Настройте политику ротации (Retention Policy): настройте автоудаление старых копий по схеме «Дедушка-Отец-Сын» (GFS), чтобы не исчерпать дисковое пространство хранилища.

9. Типичные ошибки

  • Бэкапы создаются, но restore никогда не проверялся на практике: в момент катастрофы выясняется, что архив поврежден, пароль шифрования утерян, либо версия СУБД на новом сервере несовместима с бинарным форматом дампа.
  • Хранение архивов рядом с боевой базой: при выходе из строя дискового массива или компрометации хоста уничтожаются и рабочие данные, и все копии.
  • Отсутствие контроля свободного места на сервере бэкапов: диски переполняются, ротация не срабатывает, и создание бэкапов молча прекращается на месяцы.
  • Отключенная архивация WAL/binlog при ожиданиях нулевого RPO: руководство уверено, что потери составят не более 5 минут, а реально восстановиться можно только на полночь вчерашнего дня.
  • Попытка делать только полные дампы на терабайтных базах: процесс снятия занимает 18 часов, выжигает весь дисковый I/O продакшена и не успевает завершиться до начала рабочего дня.

В следующей статье мы перейдем на уровень глобальной инфраструктуры: как проектировать катастрофоустойчивые архитектуры, способные пережить отказ целого дата-центра или региона: 16. Disaster recovery.