docs: MAM baseline 0.8.4 — best-effort archival and offline repair
Document the 'archive redo baseline changed in place' failure, the runtime session isolation, the offline storage-checkpoint repair, and the Prosody native-format comparison (list_append in-place vs list_store atomic rename).
This commit is contained in:
1 parent
100005379b
commit
75bb730d3c
3 files changed
+83
-11
No files matched your search
@@ -235,7 +235,7 @@ bind2_archive_latency_network.py, archive_edges.rs, session_routing_isolation.rs
|
|||||||
После изменений обновляйте точные границы совместимости и результаты проверки.
|
После изменений обновляйте точные границы совместимости и результаты проверки.
|
||||||
Не перезаписывайте исторические отчёты как будто они относятся к новой сборке.
|
Не перезаписывайте исторические отчёты как будто они относятся к новой сборке.
|
||||||
В передаваемый ZIP включайте AGENTS.md, workflow, vendor reference, исходники,
|
В передаваемый ZIP включайте AGENTS.md, workflow, vendor reference, исходники,
|
||||||
документацию и scripts; исключайте target, demo data, bin, .git, __pycache__, pyc
|
документацию и scripts; исключайте target, demo data, bin, .git, **pycache**, pyc
|
||||||
и секреты. Сохраняйте executable bits shell scripts и проверяйте содержимое ZIP.
|
и секреты. Сохраняйте executable bits shell scripts и проверяйте содержимое ZIP.
|
||||||
|
|
||||||
## Durable message IO 0.8.3
|
## Durable message IO 0.8.3
|
||||||
@@ -298,3 +298,34 @@ Final binary SHA-256: 8ceb8de3a2d02bc4399b8ae817dff7e3c3fe9bff83dc0c6669b7f19210
|
|||||||
Подробные samples/границы — docs/VALIDATION-0.8.3.md. Checksum и JSON syntax всех frames
|
Подробные samples/границы — docs/VALIDATION-0.8.3.md. Checksum и JSON syntax всех frames
|
||||||
проверяются при SM replay, но Record создаётся только для последнего
|
проверяются при SM replay, но Record создаётся только для последнего
|
||||||
snapshot. Recovery WAL sync до публикации обязателен; EIO fixture защищает это.
|
snapshot. Recovery WAL sync до публикации обязателен; EIO fixture защищает это.
|
||||||
|
|
||||||
|
## Monal MAM baseline 0.8.4
|
||||||
|
|
||||||
|
Баг: «archive redo baseline changed in place» на живом сервере — внешняя
|
||||||
|
перезапись native `.list` поверх зафиксированного redo-baseline (бакап/копия
|
||||||
|
data_path/Prosody/старая версия) делала каждый `archive_for_user` Err, `?` ронял
|
||||||
|
session, клиент (Monal-iOS) реконнектился и не доставлял сообщение. Причина не в
|
||||||
|
обычном append — baseline ломает только перезапись первых `base` байт в обход
|
||||||
|
`.rredo`; наш Rust-append пишет только в конец.
|
||||||
|
|
||||||
|
Фикс (commit 1000053): 1) MAM-архивация на личной доставке (отправитель,
|
||||||
|
получатель, входящая федерация) стала best-effort `archive_message_best_effort` —
|
||||||
|
storage-ошибка не роняет session и не роняет доставку, в лог `mam-archive-skipped`
|
||||||
|
(санитизированный `sanitized_label`, без payload); 2) offline `storage-checkpoint`
|
||||||
|
теперь ремонтирует непроверенный baseline: `prepare_rewrite` через
|
||||||
|
`is_untrusted_redo` считает текущий синхронизированный native авторитетным и
|
||||||
|
удаляет неприменимый журнал (`retire_redo`). Живой append остаётся fail-closed.
|
||||||
|
Новые tests: `archive.rs` `runtime_append_fails_closed_...`/
|
||||||
|
`offline_checkpoint_retires_...`, сетевой `tests/mam_broken_baseline_network.py`
|
||||||
|
(перезапись baseline не роняет доставку; checkpoint возвращает MAM).
|
||||||
|
|
||||||
|
Сравнение с Prosody: `util/datamanager.lua` `list_append` пишет в конец, а
|
||||||
|
`list_store` (перезапись) делает atomic rename — меняет первые bytes baseline;
|
||||||
|
`plugins/mod_storage_internal.lua` `archive:append` для MUC/`key` и trim/delete
|
||||||
|
делает `list_store` (полная перезапись). Prosody не понимает `.rredo` sidecar. Наш
|
||||||
|
native `.list` сохраняет Prosody-совместимый `item(...)` формат.
|
||||||
|
|
||||||
|
Операционный ремонт пользователя: остановить сервер, `./target/release/rust-xmpp
|
||||||
|
storage-checkpoint CONFIG`, запустить снова. `--experimental` не снимать. Полная
|
||||||
|
замена Prosody требует реального CI, внешней федерации, настоящих клиентов/push,
|
||||||
|
deployment/UID/TLS, rollback и длительной нагрузки — см. COMPATIBILITY.md.
|
||||||
+12
-1
@@ -8,7 +8,7 @@
|
|||||||
Это не означает полного совпадения поведения с Prosody.
|
Это не означает полного совпадения поведения с Prosody.
|
||||||
|
|
||||||
| Область | Что реализовано | Существенные пределы |
|
| Область | Что реализовано | Существенные пределы |
|
||||||
|---|---|---|
|
| ----------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||||
| Конфигурация | Lua/JSON/YAML/YML/TOML, Include, глобальные и локальные области, наследование модулей | Lua VM ограничена; не все функции окружения конфигуратора Prosody доступны. Runtime обслуживает один VirtualHost и его компоненты |
|
| Конфигурация | Lua/JSON/YAML/YML/TOML, Include, глобальные и локальные области, наследование модулей | Lua VM ограничена; не все функции окружения конфигуратора Prosody доступны. Runtime обслуживает один VirtualHost и его компоненты |
|
||||||
| Хранилище | internal `.dat`, `.list`, бинарные строки, смешанные ключи Lua, атомарные записи, потоковые архивы, инвалидирование `.lidx` | SQL, external storage остальных модулей и произвольные драйверы не реализованы; S3 uploads поддержаны. Каталог блокируется между процессами Rust; Prosody в блокировке не участвует |
|
| Хранилище | internal `.dat`, `.list`, бинарные строки, смешанные ключи Lua, атомарные записи, потоковые архивы, инвалидирование `.lidx` | SQL, external storage остальных модулей и произвольные драйверы не реализованы; S3 uploads поддержаны. Каталог блокируется между процессами Rust; Prosody в блокировке не участвует |
|
||||||
| Аккаунты, saslauth | internal_hashed SHA-1/SHA-256, SASLprep, PLAIN внутри TLS, SCRAM и PLUS с tls-exporter/tls-server-end-point, SSDP, SASL2 | Только internal_hashed; опциональный sasl2_bind2 (alias bind2) поддерживает inline bind/SM/CSI/Carbons. SASL2 inline SM resume и takeover живого транспорта реализованы; Bind2/MAM metadata читает endpoints без полного scan; полные MAM queries всё ещё могут сканировать историю |
|
| Аккаунты, saslauth | internal_hashed SHA-1/SHA-256, SASLprep, PLAIN внутри TLS, SCRAM и PLUS с tls-exporter/tls-server-end-point, SSDP, SASL2 | Только internal_hashed; опциональный sasl2_bind2 (alias bind2) поддерживает inline bind/SM/CSI/Carbons. SASL2 inline SM resume и takeover живого транспорта реализованы; Bind2/MAM metadata читает endpoints без полного scan; полные MAM queries всё ещё могут сканировать историю |
|
||||||
@@ -172,3 +172,14 @@ ad-hoc destroy/set-affiliation. Общие и host `modules_disabled` приме
|
|||||||
MAM/SM используют authoritative redo sidecars. Перед сменой writer или откатом
|
MAM/SM используют authoritative redo sidecars. Перед сменой writer или откатом
|
||||||
на старую версию требуется offline `storage-checkpoint CONFIG`; после аварии
|
на старую версию требуется offline `storage-checkpoint CONFIG`; после аварии
|
||||||
нельзя просто удалить sidecars. Подробности — [DURABLE-MESSAGE-IO.md](DURABLE-MESSAGE-IO.md).
|
нельзя просто удалить sidecars. Подробности — [DURABLE-MESSAGE-IO.md](DURABLE-MESSAGE-IO.md).
|
||||||
|
|
||||||
|
### Внешний перезапись MAM baseline
|
||||||
|
|
||||||
|
Внешняя перезапись native `.list` поверх зафиксированного redo-baseline (бакап,
|
||||||
|
копия data_path, Prosody, старая версия) давала «archive redo baseline changed
|
||||||
|
in place»: каждый MAM-append падал и через `?` ронял session, клиент
|
||||||
|
реконнектился, сообщение не доставлялось. В 0.8.4 MAM-архивация на личной
|
||||||
|
доставке стала best-effort (storage-ошибка не роняет session и не роняет доставку;
|
||||||
|
в лог — `mam-archive-skipped`), а `storage-checkpoint` получил ремонт непроверенного
|
||||||
|
baseline: текущий синхронизированный native считается авторитетным и неприменимый
|
||||||
|
журнал удаляется. Живой append остаётся fail-closed: журнал не удаляется молча.
|
||||||
@@ -66,20 +66,50 @@ in-place append при активном redo считается незаверш
|
|||||||
Редактирование baseline in place без handoff не поддержано. Anchor проверяет
|
Редактирование baseline in place без handoff не поддержано. Anchor проверяет
|
||||||
последние 4 KiB baseline, не является checksum всего старого архива.
|
последние 4 KiB baseline, не является checksum всего старого архива.
|
||||||
|
|
||||||
|
## Внешний перезапись baseline: «archive redo baseline changed in place»
|
||||||
|
|
||||||
|
Если какой-либо writer (бакап-восстановление, копия data_path, Prosody, старая
|
||||||
|
версия сервера) перезаписал native `.list` поверх зафиксированного baseline без
|
||||||
|
handoff, `.rredo` перестаёт совпадать со своим anchor. Каждый вызов
|
||||||
|
`archive_for_user` возвращал `Err`, и через `?` ошибка роняла session
|
||||||
|
(`connection-closed reason=protocol-or-transport-error`) — клиент (напр. Monal)
|
||||||
|
реконнектился по кругу, сообщение не доставлялось.
|
||||||
|
|
||||||
|
Начиная с 0.8.4 MAM-архивация на трёх местах личной доставки (отправитель,
|
||||||
|
получатель, входящая федерация) стала best-effort: при storage-ошибке исходная
|
||||||
|
stanza всё равно маршрутизируется, обе сессии остаются живы, в лог пишется
|
||||||
|
санитизированный `mam-archive-skipped`. Живой append остаётся fail-closed:
|
||||||
|
непроверенный журнал не удаляется молча, а сохраняется для явного handoff.
|
||||||
|
|
||||||
|
Ремонт выполняется той же командой offline handoff:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
rust-xmpp storage-checkpoint /etc/prosody/prosody.cfg.lua
|
||||||
|
```
|
||||||
|
|
||||||
|
Теперь `prepare_rewrite` распознаёт непроверенный baseline (changed in place,
|
||||||
|
shorter, missing, journal exceeds bound), считает текущий durably-синхронизированный
|
||||||
|
native авторитетным, синхронизирует его и удаляет неприменимый журнал. После этого
|
||||||
|
MAM history снова читается, а новые append создадут свежий redo поверх нового
|
||||||
|
baseline. Сверку совместимости native-формата см. в исходниках Prosody
|
||||||
|
(`util/datamanager.lua` `list_append`/`list_store`, `plugins/mod_storage_internal.lua`
|
||||||
|
`archive:append`): Prosody пишет `item(...)` и при полной перезаписи применяет
|
||||||
|
atomic rename — что и меняет первые bytes baseline, оставляя Rust-журнал устаревшим.
|
||||||
|
|
||||||
## Диагностика
|
## Диагностика
|
||||||
|
|
||||||
`message-processing-slow` по-прежнему имеет threshold 250 мс, duration_ms, route
|
`message-processing-slow` по-прежнему имеет threshold 250 мс, duration_ms, route
|
||||||
и connection. Новые поля в integer milliseconds:
|
и connection. Новые поля в integer milliseconds:
|
||||||
|
|
||||||
|Поле|Измеряемый этап|
|
| Поле | Измеряемый этап |
|
||||||
|---|---|
|
| ---------------- | -------------------------------------------------------------------- |
|
||||||
|pre_routing_ms|Работа до личного MAM; для MUC/ранних выходов — обработка до handled|
|
| pre_routing_ms | Работа до личного MAM; для MUC/ранних выходов — обработка до handled |
|
||||||
|sender_mam_ms|Политика и архивирование отправителя|
|
| sender_mam_ms | Политика и архивирование отправителя |
|
||||||
|recipient_mam_ms|Проверка аккаунта, политика и архивирование получателя|
|
| recipient_mam_ms | Проверка аккаунта, политика и архивирование получателя |
|
||||||
|delivery_ms|Маршрутизация, targets, mutex и transmit|
|
| delivery_ms | Маршрутизация, targets, mutex и transmit |
|
||||||
|carbons_ms|Выбор ресурсов и отправка carbon|
|
| carbons_ms | Выбор ресурсов и отправка carbon |
|
||||||
|offline_push_ms|Offline commit и подготовка/enqueue push|
|
| offline_push_ms | Offline commit и подготовка/enqueue push |
|
||||||
|handled_ms|Session mutex и durable mark_handled|
|
| handled_ms | Session mutex и durable mark_handled |
|
||||||
|
|
||||||
Неисполненные этапы равны 0. target_count — выбранные локальные ресурсы,
|
Неисполненные этапы равны 0. target_count — выбранные локальные ресурсы,
|
||||||
carbon_count — успешные carbon transmit. Это серверные этапы, не время
|
carbon_count — успешные carbon transmit. Это серверные этапы, не время
|
||||||
|
|||||||
Reference in new issue
Block a user