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

9.5 KiB
Raw Permalink Blame History

Ручная проверка БД после неопределённого восстановления

Команды maintenance-inspect и maintenance-resolve входят в текущий собранный оператор backend/dist-operator/database-writer-profile-operator.mjs. Их Linux/POSIX и PostgreSQL-приёмка прошла через локальное подключение и TLS: 16 сценариев. Опубликованный ранее 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:

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 со следующими полями:

{
  "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; при неизвестном исходном авторе используется отдельная служебная запись сверки.