Runbook — Восстановление БД из бэкапа
Техническое руководство из исходного проекта Notty. Примеры, параметры и эксплуатационные ограничения.
Этот runbook покрывает application-level restore через Notty backup API. Для инфраструктурного PITR managed PG см. документацию вашего provider'а (RDS, Cloud SQL, Neon).
Связанный документ: docs/disaster-recovery-playbook.md.
Когда использовать
| Сценарий | Уровень |
|---|---|
| Случайно удалили content type / много записей | Notty backup |
| Схема content type повреждена/откатывается | Notty backup |
| База в целом цела, но часть данных пропала | Notty backup |
| Полная потеря БД (дроп, регион упал) | managed PITR |
| Данные «нормальны», но повреждена media-библиотека | Notty backup (sections=media) |
1. Stabilize (≤ 5 мин)
- Объявить инцидент в operations-канале, назначить incident commander.
- Заморозить запись:
- в k8s:
kubectl -n notty scale deploy/notty --replicas=1+ ingress в maintenance (502/503 для/api/content/**write); - в compose: остановить webhook-генераторы и фоновые автоматизации.
- в k8s:
- Перечислить алёрты, failed jobs, dead-letter — это контекст для постмортема.
- Сделать новый snapshot текущего (повреждённого) состояния — чтобы можно было откатить даже наш «правильный» restore, если сделаем хуже.
2. Выбрать snapshot
curl -fsS -H "Authorization: Bearer $ADMIN_TOKEN" \
"$BASE_URL/api/admin/backups?status=completed&limit=10" | jq
Выберите последний snapshot до момента инцидента. Время создания и хеш содержимого — в catalog'е.
3. Dry-run
Никогда не делайте full restore без dry-run:
ADMIN_TOKEN=... BASE_URL=https://cms.example.com \
./deployment/scripts/restore.sh --dry-run --backup-id <id>
Что проверяете в ответе:
success: true;- секции, которые планируете восстанавливать, согласованы со схемами;
- нет
errors/mismatches.
Если есть несовместимость схем (новый код / старый snapshot или наоборот) —
не делайте restore. Сначала приведите версии в согласие
(upgrade.md / rollback.md).
4. Full restore
./deployment/scripts/restore.sh --backup-id <id>
# либо с явными секциями:
./deployment/scripts/restore.sh --backup-id <id> \
--sections schemas,components,config,content,media
Что увидите:
success: trueв ответе;- audit log запишет
backup.restore; - активные операционные алёрты могут перейти в acknowledged.
Полный restore блокирует БД на время операции. Если duration больше комфортного window — заранее тестируйте на staging, чтобы знать длительность.
5. Post-restore validation
-
verify-deploy.shзелёный. -
GET /api/admin/jobs/stats— нет растущей backlog'и. -
GET /api/webhooks/dead-letter— пусто или объяснимо. -
GET /api/admin/operational-alerts/stats— алёрты гаснут. - Критические content type читаются через Content API.
- Scheduled-jobs живы и в правильных таймзонах.
- Media-файлы реально доступны (открыть несколько случайных через UI).
6. Размораживание трафика
- Снять maintenance в ingress;
kubectl scale deploy/notty --replicas=<N>обратно;- мониторить ошибки/latency 30 мин.
Если restore сделал хуже
Вы должны были снять snapshot текущего состояния в шаге 1. Повторите шаги 2-5 с этим «защитным» snapshot'ом — вернёт вас в состояние до restore-попытки.
Postmortem
Через 24 часа после инцидента — постмортем с темплейтом из
incident-response.md. Добавьте:
- какой snapshot был выбран и почему;
- реальный RPO/RTO;
- какие сигналы привели к решению о restore;
- что добавим в drill (см.
backup-automation.md).
Источник: docs/operations/runbooks/database-restore.md. Снимок документации исходного проекта. Технический справочник сохраняет язык оригинала.