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

4.9 KiB
Raw Blame History

Итоги: хранение собранных адресов в 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) для них подготовлена.