Files
MikrotikManager/docs/mcp-database-maintenance.md
T

75 lines
9.5 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.
# Ручная проверка БД после неопределённого восстановления
Команды `maintenance-inspect` и `maintenance-resolve` входят в текущий собранный оператор `backend/dist-operator/database-writer-profile-operator.mjs`. Их Linux/POSIX и PostgreSQL-приёмка прошла через локальное подключение и TLS: [16 сценариев](mcp-linux-maintenance-resolution-acceptance-20261103.json). Опубликованный ранее preview-образ этим отчётом не обновляется.
После неопределённого восстановления обычные HTTP/MCP-запросы, планировщик и приём NetFlow остаются закрытыми. Существующий административный путь явного восстановления доступен. Не повторяйте прежнее действие автоматически: отсутствие ответа не означает, что данные не изменились.
Этот порядок позволяет человеку принять **наблюдаемое текущее состояние**. Он не доказывает соответствие данных исходному архиву и не превращает старые `unknown` в успешные операции.
## Подготовка
1. Остановите управляемый backend штатным способом. Сохраните его состояние и параметры запуска. PostgreSQL должна остаться доступной оператору; параллельное обслуживание БД недопустимо.
2. Выберите проверенный образ с текущими командами оператора. Используйте существующий том состояния MCP, а не новый пустой том.
3. Запускайте оператор от фактического владельца тома, с тем же UID, что использует backend. Каталоги должны принадлежать ему и быть закрыты от других пользователей; файлы входных данных — иметь права `0600`. Команда не исправляет владельцев и права автоматически.
4. Подготовьте отдельный закрытый каталог входных данных и отдельный каталог результатов. Монтируйте их только в контейнер оператора, не в обычный backend/MCP. Пароли передаются в защищённом файле транспорта, не в аргументах команды.
Нужны два независимо проверенных файла:
- `runtime-target.json`: `format=database-maintenance-runtime-target-v1`, `databaseUrl` с адресом, портом и именем настроенной БД **без имени пользователя и пароля**. Это конфигурация назначения backend, а не произвольная другая БД.
- `transport.json`: `format=database-maintenance-transport-v1`, выбранный `mode` и `connection` с полями `host`, `port`, `user`, `password`, `database`.
Для `mode=tls` дополнительно нужны `tls.serverName`, `tls.spkiSha256`, защищённый CA-файл и его проверенный SHA256. TLS — режим по умолчанию; после его ошибки переключения на незашифрованное соединение нет.
Для обычной Docker-установки без TLS поддерживается явный `mode=local-loopback`. Отдельный контейнер оператора должен присоединиться к сетевому пространству **точного проверенного контейнера PostgreSQL**: `--network "container:$REVIEWED_PG_ID"`. В `connection.host` допустимы только `127.0.0.1` или `::1`; параметры CA в этом режиме запрещены. Host networking и Docker socket не нужны. Настроенное назначение backend в `runtime-target.json` при этом сохраняется.
## Инспекция
В отдельном контейнере оператора выполните команду с проверенными путями и SHA256:
```sh
node backend/dist-operator/database-writer-profile-operator.mjs maintenance-inspect \
--state-dir /app/data/mcp \
--transport /run/review/transport.json --transport-sha256 "$TRANSPORT_SHA256" \
--runtime-target /run/review/runtime-target.json --runtime-target-sha256 "$TARGET_SHA256" \
--output /run/output/inspection.json
```
Для TLS добавьте `--ca /run/review/ca.pem --ca-sha256 "$CA_SHA256"`. `/app/data/mcp` — пример: используйте фактический `MCP_STATE_DIR` установки.
Инспекция только читает БД. Она проверяет физическую идентичность PostgreSQL, текущие миграции и схему, внешний журнал, поколение доступа и квитанции. Необязательная служебная схема `mmapp_control` не требуется для обычной установки. Результат содержит частные сведения о схеме; храните его в закрытом каталоге.
Если `humanApprovalRequired=false` и состояние уже принято, повторное разрешение не требуется. Не создавайте вторую запись ради подтверждения потерянного ответа.
## Решение человека
Человек отдельно проверяет инспекцию и создаёт защищённый `approval.json` со следующими полями:
```json
{
"format": "database-maintenance-current-state-approval-v1",
"resolutionId": "<новый UUID>",
"decision": "accept-observed-current-state",
"actorId": "<идентификатор оператора>",
"inspectionSha256": "<проверенный SHA256 inspection.json>",
"issuedAt": "<UTC ISO timestamp>",
"expiresAt": "<UTC ISO timestamp, не более 15 минут после issuedAt>",
"managedBackendStopped": true,
"historicOutcomesRemainUnknown": true,
"automaticRestore": false
}
```
Приложение и модель не создают это решение за человека. Проверенный SHA256 разрешения передаётся отдельно. Инспекция и разрешение должны оставаться действительными до публикации решения.
Вызовите `maintenance-resolve` с теми же параметрами назначения и транспорта, добавив `--inspection FILE --inspection-sha256 SHA --approval FILE --approval-sha256 SHA`. Параметр `--output` здесь не используется.
Оператор повторно читает текущее состояние, сверяет его с инспекцией и разрешением, завершает SQL-владельца и публикует неизменяемую fsync-запись решения вне PostgreSQL. Исходные журнал, квитанции и поколение доступа не переписываются. DDL, восстановление архива и выдача дополнительных SQL-прав не выполняются.
## Возобновление и повторная проверка
После подтверждённого решения запустите backend штатным способом и проверьте его готовность. Проверка при старте должна разрешить только точно покрытую историческую неопределённость. Новая незавершённая операция, изменение покрытых файлов, другое назначение БД, повреждённая запись или оставшийся lease снова блокируют запуск до SQL.
Если ответ `maintenance-resolve` потерян, начните с новой инспекции: существующее историческое решение должно быть прочитано, а не опубликовано повторно. Не удаляйте lease или записи решения по возрасту/PID. Подтверждённое историческое решение сохраняет силу после истечения срока использованного разрешения; новое решение требует нового разрешения.
Исторические `unknown` остаются такими в квитанциях. В SQL-аудит импортируются только действительно подтверждённые квитанции `applied`; при неизвестном исходном авторе используется отдельная служебная запись сверки.