Restoring a backup with no data while sources are configured now sets the db_recreated.json marker (503 until data is collected), and the backup job skips copying an empty database in that state. Adds finding 11 to the review. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
5.2 KiB
План: защита от восстановления из пустой копии (находка 11)
Источник: трассировка _recover() по графу знаний и проверка запуском (см. docs/review-2026-09-21.md, находка 11).
Проблема
_recover ставит на место повреждённой базы самую свежую исправную копию, но не смотрит на её содержимое. Если копия пуста (ночное задание backup сработало до первого сбора или во время его сбоев), а источники в config.json настроены, то после порчи базы API отвечает 200 [] без метки: та же угроза, что в находке 1 (потребитель может принять пустой список за истину), только через восстановление. Подтверждено запуском: копия пустой базы -> порча -> /addresses даёт 200 [], метки нет.
Дизайн
- Признак «пусто несмотря на источники»:
db.empty_despite_sources(conn): в базе нет ни одного значения, а вconfig.jsonнастроен хотя бы один ASN или FQDN. Сначала проверяется число значений (конфиг не читается, если данные есть); нечитаемый конфиг при пустой базе считается «пусто» (блокировка по умолчанию). Критерий намеренно общий, а не по типам: копия, где есть ASN, но нет адресов FQDN (например, все адреса отфильтрованы как неглобальные), не должна вечно держать выдачу в ожидании. - Восстановление: после успешного
_restore_backupприempty_despite_sourcesпишется та же меткаdb_recreated.json(с полемreason). Дальше работает уже существующая защита:/addressesи/addresses/diffдают503сRetry-After,/healthпоказываетdegradedиdb_recreated, сборщик снимает метку, когда данные собраны. Восстановление копии с данными метку не ставит. - Задание
backup: пустую базу при настроенных источниках не копирует:backup_databaseвозвращаетNone(не ошибка: статус задания остаётся успешным, в лог пишется сообщение), ротация не выполняется, существующие копии не затрагиваются. Так пустые копии не вытесняют хорошие заbackup_keepдней и не появляются вовсе. Пустая база без источников копируется как раньше.
Изменения
db.py:empty_despite_sources;recreated_pendingиспользует общий разбор конфигурации; метка ставится в_recover(общая функция записи метки для обеих веток);backup_databaseвозвращаетNoneдля пустой базы при источниках.collector_daemon.py:run_backupобрабатываетNone(сообщение в лог).README.md: разделы о резервной копии и автовосстановлении.docs/review-2026-09-21.md: находка 11; итоги вdocs/summary-empty-backup-guard.md.- Тесты (1 новый, всего 28): пустая база при настроенных источниках копию не создаёт, копия с данными восстанавливается без метки, пустая копия (снятая, когда источников не было) при появлении источников даёт метку и
503-состояние.
Не входит
Тип-специфичное ожидание при восстановлении (см. выше); копии вне сервера; удаление уже существующих пустых копий (при необходимости - вручную из backups/).
Проверка
Тесты в контейнере; повтор запуска, воспроизводившего проблему: восстановление из пустой копии при настроенном источнике теперь даёт 503, метка есть, после появления данных выдача возобновляется; копия с данными - без метки.
Откат
Убрать проверку в _recover и backup_database (возврат к предыдущему коммиту); схема данных не затрагивается, метку можно удалить вручную.