- секции `workouts` и `stateOfMind` покрыты разбором: тренировка лежит одной строкой вместе с маршрутом и внутренними рядами, запись — по ключу `род + id`; миграция 00007 заводит обе таблицы и возвращает в очередь `partial`-доставки с этими ключами - сущность заменяется целиком, но условно: приехавшая побеждает, если не теряет содержания сохранённой (множество ключей и длины верхнеуровневых массивов), а при равном содержании выигрывает версия из более поздней доставки ЖУРНАЛА — «побеждает приехавшая» было бы функцией порядка свёртки, и живая витрина расходилась бы с пересборкой молча - отпечаток витрины покрывает тренировки и записи и снимается одним снимком базы; отчёт `reindex` считает «было и стало» по каждой единице хранения
64 lines
5.2 KiB
Markdown
64 lines
5.2 KiB
Markdown
# Ретеншен сырого архива
|
||
|
||
**Приоритет:** низкий
|
||
|
||
Срок жизни сырого архива объявлен (14 дней, `storage.raw_retention`), но
|
||
удаления нет: архив растёт бесконечно. Пока это 16 МБ и проблемой не является.
|
||
|
||
**Само правило изменилось.** Экспорт Apple — снапшот всей истории, доставки
|
||
после его даты — события поверх снапшота, и состояние всегда пересобираемо
|
||
свёрткой. Значит доставки должны жить **до следующего проверенного экспорта**,
|
||
а не фиксированные две недели: иначе между концом ретеншена и датой снапшота
|
||
образуется дыра в журнале, и пересобрать этот отрезок будет нечем.
|
||
|
||
Цена измерена: ~23 МБ архива в сутки, то есть ~2 ГБ за квартал между
|
||
экспортами. Дёшево за возможность пересобрать что угодно.
|
||
|
||
Отдельное исключение: `stateOfMind` в экспорт не попадает вовсе (проверено на
|
||
свежем архиве). Для него доставки — не хвост журнала, а единственный источник,
|
||
и под общее правило удаления он не подпадает.
|
||
|
||
Включать **после** того, как разбор устоится и пересборка докажет, что
|
||
хранилище действительно восстанавливается: иначе страховка исчезнет раньше, чем
|
||
перестанет быть нужна.
|
||
|
||
Готово, когда удаляются только доставки старше последнего проверенного
|
||
экспорта, записи `stateOfMind` не трогаются вовсе, а `/stats` показывает
|
||
глубину архива и дату снапшота, до которой он подрезан.
|
||
|
||
## Предусловие снова открыто
|
||
|
||
Признак «доставка с непокрытой секцией» появился в change
|
||
`2026-08-01-nerazobrannye-sekcii-dostavki` и работал заодно защитой
|
||
`stateOfMind`: такие доставки числились `partial`, и ретеншен их не тронул бы.
|
||
|
||
Change `2026-08-02-trenirovki-i-zapisi` покрыл `stateOfMind` разбором, и защита
|
||
исчезла: доставка из одного состояния разума теперь получает `parsed` с пустым
|
||
списком непокрытых, то есть **побайтово неотличима** от доставки из метрик — а
|
||
метрики восстановимы из экспорта Apple, состояние разума нет (находка 46).
|
||
Ретеншен, написанный по правилу «удаляем всё, что не `partial`», сотрёт ровно те
|
||
тела, которых в экспорте не существует, и первая же пересборка потеряет историю
|
||
состояния разума навсегда.
|
||
|
||
Значит признак невосстановимости нужен **не производный от «непокрытости»**.
|
||
Варианты:
|
||
|
||
- **Перечень покрытых секций, которых нет в экспорте Apple** рядом с доставкой
|
||
(сегодня — ровно `stateOfMind`). Цена: колонка и строка в свёртке; читается
|
||
так же, как `uncovered_sections`, и одним запросом.
|
||
- **Признак у доставки «тело — единственный источник»**, выставляемый разбором.
|
||
Цена та же, но смысл шире и требует решения, что считать единственным
|
||
источником для будущих секций.
|
||
- **Никогда не подрезать тела доставок, у которых есть строки в `record`.**
|
||
Цена нулевая по схеме, но неточная: провенанс записи указывает на доставку
|
||
её **текущей** версии, а копий у записи бывает по 26.
|
||
|
||
Рекомендация — первый вариант: он прямо отвечает на вопрос «что останется
|
||
потерянным», как это уже делает `uncovered_sections`, и не требует додумывать
|
||
семантику.
|
||
|
||
Вместе с этим действует правило: задача, которая начинает разбирать секцию, тем
|
||
же изменением переводит `partial`-строки с этим ключом в `pending` (так сделала
|
||
миграция `00007`). Ретеншену позволено смотреть на `partial` только пока правило
|
||
соблюдается.
|