Files
ripe-cidr-collector/docs/summary-sqlite-storage.md
T
ayurishchevandClaude Sonnet 5 bcf8156085 Initial commit: RIPE CIDR/FQDN collector
Collector daemon, FastAPI server (addresses, diff, collect, sources),
SQLite storage with change journal, Docker Compose deployment,
tests, documentation and project rules.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-21 07:29:38 +03:00

28 lines
4.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Итоги: хранение собранных адресов в SQLite
План: `docs/plan-sqlite-storage.md`.
## Сделано
- **`db.py` (новый)**: SQLite (`ripe.db`, WAL), таблица `addresses(kind, source, value, first_seen, last_seen)`, `user_version`; `connect`/`session`/`transaction`, `merge_source` (upsert + TTL), `sweep_unconfigured`, `purge_source`, `get_values`, `count_values`.
- **Миграция**: при первом открытии базы `data.json` и `fqdn_data.json` импортируются одной транзакцией (`BEGIN IMMEDIATE`, параллельный старт безопасен), `first_seen`/`last_seen` сохраняются (старый формат без них: `last_seen` = момент миграции); оригиналы переименовываются в `*.migrated-<ts>` (резервная копия и путь отката).
- **`cidr_collector.py`**: сбор пишет в БД одной транзакцией (конфиг перечитывается внутри неё, удалённый во время сбора источник не воскресает); удалены JSON-хранилище, `merge_entry`, `purge_entry`, файловые блокировки данных. Блокировка конфига (`update_config`) осталась.
- **`api_server.py`**: чтение адресов, счётчики `/health` и `purge` работают через БД; `sqlite3.Error` и `StorageError` -> 503.
- **Порча базы**: `not a database`/`malformed` -> файл (с `-wal`/`-shm`) переименовывается в `ripe.db.corrupt-<ts>`, `StorageError` (503); `database is locked` не считается порчей и файл не трогает.
- **Развёртывание**: `db.py` добавлен в `Dockerfile`; `*.db`, `*.db-wal`, `*.db-shm`, `*.migrated-*` в `.gitignore`/`.dockerignore`; README: раздел 9 (схема, миграция, откат, бэкап), обновлены логика сбора и раздел Docker.
- **Тесты**: тесты на JSON переведены на БД, добавлены проверка порчи базы (в существующем тесте) и `tests/test_db.py` (импорт старого/нового формата, идемпотентность). Всего 14, в контейнере 14 passed.
## Проверка
- **Эталон**: на копии реальных данных ответы `/addresses?type=all|cidr|fqdn` после миграции побайтно совпадают со снятыми старой JSON-версией; повторный старт ничего не импортирует.
- Сбор: 6 ASN и 3 FQDN обновлены, повторный запуск дубликатов не создаёт (49 = 49 уникальных).
- Конкурентность: 60 запросов `/addresses` во время сбора - все 200; 15 прогонов по 5 процессов, одновременно мигрирующих чистую копию, - без ошибок, ровно один импорт.
- Порча: мусор в `ripe.db` -> 503, файл убран в `*.corrupt-*`.
- Docker Compose (два контейнера, один том): миграция в томе, эталон совпал, демон записывает, API читает, `purge` виден, после `down`/`up` данные на месте; стенд убран.
## Замечания
- После порчи базы следующие запросы вернут пустой список (создаётся новая пустая база), пока сборщик не наполнит её заново; повреждённый файл сохранён как `*.corrupt-*`. Это осталось прежним поведением, автоматического восстановления из копии нет.
- Резервное копирование не автоматизировано (в README описана команда `sqlite3 ".backup"`), это можно добавить заданием демона.
- Сообщение лога «... data saved» теперь пишется после каждой транзакции, даже если ничего не изменилось.
- Первый запуск на реальных данных: запись `google.com` (нет в конфигурации) станет стареть по TTL, её адрес удалится через 90 дней после миграции; `last_seen` старых записей после миграции = момент миграции.
- WAL не рекомендуется на сетевых ФС.
- Хранение истории изменений и `?since=` в этот шаг не входили; схема (`first_seen`/`last_seen`) для них подготовлена.