Перейти к содержанию

Раздел 3. Сохранение и восстановление данных

Настоящий раздел устанавливает административный регламент резервного копирования и восстановления данных BOX5-DIT-MGSN. Технологические действия по развёртыванию, настройке узлов, лицензированию и общему восстановлению поставки приведены в документе И2, раздел 2 и И2, раздел 3. В данном разделе фиксируются границы ответственности администратора: что сохранять, когда выполнять копирование, как проверять пригодность копии и как возвращать данные в работающий контур.

Пути к данным зависят от контура и определяются переменными окружения поставки. В командах ниже используется обозначение COMPOSE_DATA. Для актуального промышленного контура на мастер-ноде используется /data/compose-data2; данные песочницы Node-RED находятся в отдельном каталоге /data/sandbox-compose-data.

Состав резервной копии и восстановление данных

3.1. Порядок резервного копирования

3.1.1. Общие правила

Резервное копирование выполняется до любого обновления, перед ручным изменением конфигурации, после успешной приёмки новой поставки и по периодическому регламенту площадки. Для ежедневной защиты учётных данных и прав доступа в промышленном контуре при включённой штатной схеме backup используются sidecar-контейнеры pg-backup; для целостного восстановления всего контура требуется файловая копия COMPOSE_DATA, конфигурации и данных песочницы, созданная в технологическое окно.

Основные правила:

  • копия должна храниться вне восстанавливаемого каталога данных; для аварийного сценария требуется копия на другом диске или внешнем хранилище;
  • перед файловым копированием PostgreSQL, ClickHouse, Kafka и MinIO контур останавливается, иначе копия может быть несогласованной;
  • .env-файлы, файлы лицензии, токены и пароли входят в закрытую резервную копию администратора, но не публикуются в документации, Git, тикетах и общих чатах;
  • временные IPC/HLS-каталоги, например /tsm_tmpfs, /mnt/ram0, /tmp/inference_ipc, не считаются источником долговременных данных и пересоздаются при запуске;
  • Kafka в отдельных контурах может использовать tmpfs для ускорения работы; такая шина не рассматривается как долговременное хранилище бизнес-данных;
  • пригодность копии подтверждается не только фактом создания файла, но и проверкой gzip/архива, контрольными суммами и периодическим тестовым восстановлением.

3.1.2. Состав резервной копии

Объект Где хранится Способ копирования Контроль
Код поставки и конфигурация ~/CODE/box3, ~/CODE/node-red-sandbox, domains.conf, per-domain .env, ui-rest/ui-config, настройки sandbox rsync -a --numeric-ids в закрытый каталог резервных копий Зафиксированы commit/tag, список Docker-образов, рабочие .env и runtime-конфигурация UI/sandbox.
PostgreSQL st-auth и st-access ${COMPOSE_DATA}/statistics/st-auth-postgres, ${COMPOSE_DATA}/statistics/st-access-postgres, дампы ${COMPOSE_DATA}/backups/st-auth, ${COMPOSE_DATA}/backups/st-access Ежедневный pg-backup по cron 0 1 * * *; ручной /pg-backup.sh make_backup; файловая копия PGDATA только на остановленном контуре latest.psql.gz существует, gzip -t успешен, заголовок начинается с PostgreSQL database dump, тестовый restore проходит.
Остальные PostgreSQL БД Каталоги pgdata-* и сервисные PostgreSQL-каталоги под ${COMPOSE_DATA}: статистика, события, камеры, отчёты, severstal, inference Файловая копия остановленного контура; при наличии отдельного helper-контейнера - также SQL dump После восстановления контейнер PostgreSQL стартует, прикладной сервис проходит миграции/health-проверку.
ClickHouse ${COMPOSE_DATA}/statistics/*click-house-data, Superset/витринные каталоги Файловая копия только после остановки соответствующих сервисов Контейнеры ClickHouse запускаются, таблицы событий и агрегатов читаются через UI/API.
Redis Redis-каталоги под ${COMPOSE_DATA} при наличии bind mount; часть Redis используется только как кэш Файловая копия остановленного контура, если состояние критично; кэш допускается пересоздать Сервисы, зависящие от Redis, стартуют без повторяющихся ошибок; кэши прогреваются заново.
Kafka и Schema Registry ${COMPOSE_DATA}/kafka3.4/kafka-data, ${COMPOSE_DATA}/severstal/*kafka*, ASUTP schema registry Файловая копия остановленного контура при необходимости сохранить offsets/topics; в штатном восстановлении допускается пересоздание шины и replay из БД/сервисов Kafka-контейнеры стартуют, потребители не падают из-за отсутствующих топиков.
MinIO, DTS, отчёты, видео и ассеты ${COMPOSE_DATA}/data-storage/minio_data, ${COMPOSE_DATA}/asset-storage, ${COMPOSE_DATA}/report-pdf-xlsx-generator, ${COMPOSE_DATA}/vc_videos, ${COMPOSE_DATA}/inference/video-*, ${COMPOSE_DATA}/severstal/archive-videos Файловая копия остановленного контура Объекты открываются через /api/s3/*, отчёты скачиваются, видеофрагменты связаны с событиями.
Инференс, NRI и модели ${COMPOSE_DATA}/converted, ${COMPOSE_DATA}/models-registry, ${COMPOSE_DATA}/inference/*, при наличии отдельный MODELS_STORAGE; данные sandbox в /data/sandbox-compose-data rsync -a --numeric-ids; модели и sandbox копируются до замены сценариев и после успешной конвертации inf-nri-inference, svr-models-registry, inf-load-balancer запускаются; модели доступны через runtime-проверки.
Лицензирование и host-настройки ${COMPOSE_DATA}/guardant при bind mount, файлы оффлайн-активации Guardant, /etc/docker/daemon.json, /etc/fstab, /etc/systemd/system/box-restart.service Закрытая копия администратора; системные файлы копируются с сохранением владельцев и прав Guardant подтверждает активацию, Docker использует корректный runtime, tmpfs и автозапуск восстановлены.

3.1.3. Выполнение резервного копирования

  1. Согласовать технологическое окно и уведомить пользователей о возможной недоступности web-интерфейса и обработки видеопотоков.
  2. Зафиксировать текущее состояние окружения:
cd ~/CODE/box3
date -Is
compose.sh status all
docker compose ls
docker ps --format 'table {{.Names}}\t{{.Image}}\t{{.Status}}'
grep -h '^COMPOSE_DATA=' .env */.env 2>/dev/null | sort -u
git rev-parse --short HEAD || true
  1. Проверить свободное место. Размер резервной копии должен покрывать COMPOSE_DATA, sandbox и запас на новые дампы:
df -h
du -sh /data/compose-data2 /data/sandbox-compose-data 2>/dev/null
  1. Выполнить ручной dump для штатных PostgreSQL sidecar-контейнеров, если они присутствуют:
docker exec -u 1000:1000 statistics-st-auth-postgres-backup-1 \
  /pg-backup.sh make_backup
docker exec -u 1000:1000 statistics-st-access-postgres-backup-1 \
  /pg-backup.sh make_backup
  1. Проверить свежие дампы:
for d in \
  /data/compose-data2/backups/st-auth \
  /data/compose-data2/backups/st-access
do
  test -L "$d/latest.psql.gz"
  gzip -t "$d/latest.psql.gz"
  zcat "$d/latest.psql.gz" | head -n 3
done
  1. Остановить основной compose-контур для целостного файлового копирования:
cd ~/CODE/box3
compose.sh stop all

Если в окружении используется swarm-профиль, вместо compose.sh применяется штатный скрипт из документа И2: ./utils/swarm/swarm.sh stop.

  1. Остановить песочницу Node-RED, если она входит в резервную копию:
cd ~/CODE/node-red-sandbox
docker compose down
  1. Скопировать данные в каталог резервной копии. Имя каталога должно содержать окружение, дату и краткий идентификатор версии:
backup_root=/data/backups/sova-prod-$(date +%F-%H%M)
compose_data=/data/compose-data2

mkdir -p "$backup_root"
rsync -a --numeric-ids ~/CODE/ "$backup_root/CODE/"
rsync -a --numeric-ids "$compose_data"/ "$backup_root/compose-data/"
rsync -a --numeric-ids /data/sandbox-compose-data/ \
  "$backup_root/sandbox-compose-data/"

sudo cp /etc/docker/daemon.json "$backup_root/" 2>/dev/null || true
sudo cp /etc/fstab "$backup_root/fstab" 2>/dev/null || true
sudo cp /etc/systemd/system/box-restart.service \
  "$backup_root/" 2>/dev/null || true
  1. Сформировать контрольные суммы и краткий паспорт копии:
du -sh "$backup_root"
find "$backup_root" -type f -print0 | sort -z \
  | xargs -0 sha256sum > "$backup_root.sha256"
{
  echo "backup_id=$(basename "$backup_root")"
  echo "created_at=$(date -Is)"
  echo "host=$(hostname)"
  docker compose ls
} > "$backup_root.MANIFEST.txt"
  1. Запустить контур и проверить состояние:

    cd ~/CODE/box3 && compose.sh start all
    cd ~/CODE/node-red-sandbox && docker compose up -d
    cd ~/CODE/box3 && compose.sh status all
    curl -fsS http://localhost/api/base/ping/
    

3.1.4. Хранение и ротация

Срок хранения задаётся эксплуатационным регламентом площадки. Технический минимум для контейнеров deploy-utils/pg-backup задаётся переменной MAX_BACKUPS; если она не переопределена, скрипт хранит до 62 файлов, учитывая ссылку latest.psql.gz. Для полной копии окружения рекомендуется хранить не менее одной копии до обновления, одной копии после обновления и нескольких периодических копий, достаточных для расследования инцидентов.

Каталог резервных копий должен иметь ограниченные права доступа. Перед передачей копии за пределы контура администратор проверяет, что в открытые каналы не попадают .env, файлы лицензии, пароли, токены, дампы БД и персональные данные.

3.1.5. Верификация резервного копирования

Для каждой созданной копии выполняются проверки:

Проверка Команда/действие Норма
Наличие свежего SQL dump ls -lh ${COMPOSE_DATA}/backups/*/latest.psql.gz Ссылка указывает на файл текущей даты или даты регламентного окна.
Целостность gzip gzip -t latest.psql.gz Команда завершается без ошибки.
Признак PostgreSQL dump zcat latest.psql.gz \| head -n 3 В заголовке указано PostgreSQL database dump.
Контрольные суммы файловой копии sha256sum -c <backup_id>.sha256 Все файлы проходят проверку.
Тестовое восстановление Восстановление dump в одноразовую PostgreSQL БД или на отдельный тестовый контур restore завершается успешно, таблицы читаются.
Проверка после запуска compose.sh status all, curl /api/base/ping/, выборочная проверка UI/API Контейнеры Up, API отвечает, критичные данные доступны.

Для промышленного контура проверка backup-контейнеров включает:

  • активные backup-контейнеры: statistics-st-auth-postgres-backup-1 и statistics-st-access-postgres-backup-1;
  • оба контейнера используют образ docker.vizorlabs.ru/deploy-utils/pg-backup:master, cron 0 1 * * * и mount ${COMPOSE_DATA}/backups/<service> в /backup;
  • ручной /pg-backup.sh make_backup создаёт свежий архив <timestamp>.psql.gz;
  • gzip -t /backup/latest.psql.gz прошёл успешно, заголовок дампа указывает PostgreSQL database dump;
  • restore выбранного дампа проверен на одноразовом PostgreSQL-контейнере или отдельной тестовой БД; скрипт завершил Clean, Recreate и Restore со статусом succeeded, после восстановления таблицы схемы читаются.

3.2. Порядок восстановления

3.2.1. Подготовка к восстановлению

Восстановление выполняется только после определения границ сбоя. До замены данных администратор сохраняет текущее повреждённое состояние в отдельный каталог, чтобы можно было провести расследование или повторить восстановление с другой копии.

Порядок подготовки:

  1. Зафиксировать время инцидента, контур, симптомы, список затронутых сервисов и идентификатор выбранной резервной копии.
  2. Проверить контрольные суммы копии:
sha256sum -c /data/backups/<backup_id>.sha256
  1. Убедиться, что версия ~/CODE, Docker-образы и структура каталогов соответствуют резервной копии. Нельзя смешивать БД, MinIO и ClickHouse из разных backup_id без отдельного решения ответственного администратора.
  2. Остановить сервисы, которые могут писать в восстанавливаемые данные.
  3. Выполнить восстановление минимальной достаточной области: отдельная БД, отдельный каталог, sandbox или весь контур.
Область сбоя Что останавливать Основной способ восстановления
БД st-auth или st-access Web gateway и прикладной сервис, который пишет в БД; PostgreSQL должен быть доступен для restore /pg-backup.sh restore /backup/<archive>.psql.gz.
Любая другая PostgreSQL БД Пишущие сервисы домена или весь домен Восстановить PGDATA из остановленной файловой копии или использовать отдельный dump, если он настроен.
ClickHouse/MinIO/Kafka Соответствующий домен или весь контур Восстановить каталог данных из той же файловой копии.
Потеря COMPOSE_DATA Весь compose/swarm-контур Полное восстановление COMPOSE_DATA, затем запуск доменов.
Потеря sandbox node-red-sandbox compose-проект Восстановить /data/sandbox-compose-data, права и .env.
Потеря моделей/converted Inference и sandbox при необходимости Восстановить converted, models-registry, MODELS_STORAGE; перезапустить inference.

3.2.2. Восстановление st-auth и st-access из SQL dump

/pg-backup.sh restore является разрушительной операцией: скрипт выполняет dropdb, затем createdb и загружает dump через psql. Команду выполняют только в технологическое окно и только для выбранной целевой БД.

Пример для st-access:

archive=/backup/latest.psql.gz

docker stop ui-rest-ui-rest-to-gprc-1 statistics-st-access-1
docker exec statistics-st-access-postgres-backup-1 \
  /pg-backup.sh restore "$archive"
docker exec statistics-st-access-postgres-backup-1 \
  cat /status/status.txt
docker start statistics-st-access-1 ui-rest-ui-rest-to-gprc-1

Для st-auth используется тот же порядок, но контейнеры statistics-st-auth-postgres-backup-1 и statistics-st-auth-1.

После восстановления выполнить:

cd ~/CODE/box3
compose.sh status statistics
compose.sh status ui-rest
curl -fsS http://localhost/api/base/ping/

Если /status/status.txt содержит false или файл отсутствует, восстановление считается неуспешным. Необходимо сохранить вывод команды, не запускать пользовательский доступ к сервису и повторить восстановление из другой копии или эскалировать инцидент.

3.2.3. Восстановление файловой копии COMPOSE_DATA

Полное восстановление применяется при потере диска, повреждении нескольких БД, повреждении MinIO/ClickHouse или после неуспешного обновления, когда требуется вернуть весь контур к согласованному состоянию.

cd ~/CODE/box3
compose.sh stop all

compose_data=/data/compose-data2
backup_root=/data/backups/<backup_id>

sudo mv "$compose_data" "${compose_data}.broken-$(date +%F-%H%M)"
sudo mkdir -p "$compose_data"
sudo rsync -a --numeric-ids "$backup_root/compose-data/" "$compose_data/"

cd ~/CODE/box3
compose.sh start all
compose.sh status all

Если восстанавливается контур в swarm-профиле, вместо compose.sh stop/start all используется ./utils/swarm/swarm.sh stop/start, а каталоги данных должны быть восстановлены на каждой ноде, где они локально хранятся.

3.2.4. Восстановление конфигурации и кода поставки

Конфигурацию восстанавливают вместе с версией поставки, для которой была сделана резервная копия. Перед заменой текущий ~/CODE сохраняется отдельно.

backup_root=/data/backups/<backup_id>

mv ~/CODE ~/CODE.broken-$(date +%F-%H%M)
rsync -a --numeric-ids "$backup_root/CODE/" ~/CODE/

cd ~/CODE/box3
compose.sh check all
compose.sh start all

После восстановления проверить:

  • domains.conf содержит актуальный список доменов и порядок старта;
  • доменные .env-файлы соответствуют целевому контуру и версии поставки;
  • ui-rest/ui-config/config.json указывает корректные адреса UI, sandbox и внешних сервисов;
  • .env-файлы доступны только администраторам и не отличаются от выбранной резервной копии по критичным параметрам.

3.2.5. Восстановление песочницы Node-RED

cd ~/CODE/node-red-sandbox
docker compose down

backup_root=/data/backups/<backup_id>
sudo mv /data/sandbox-compose-data \
  /data/sandbox-compose-data.broken-$(date +%F-%H%M)
sudo mkdir -p /data/sandbox-compose-data
sudo rsync -a --numeric-ids \
  "$backup_root/sandbox-compose-data/" /data/sandbox-compose-data/
sudo chown -R 1000:1000 /data/sandbox-compose-data

docker compose up -d
docker compose ps

После запуска проверить доступность /sandbox/, наличие сценариев в Node-RED, доступность flows.json, node-red-vl-configs и NRI assets. Если после восстановления изменились модели, выполнить контрольную конвертацию и загрузку моделей по процедуре И2.

3.2.6. Восстановление моделей и инференса

Модели и NRI-сценарии должны соответствовать версии кода inference, svr-models-registry и sandbox. При частичном восстановлении старые каталоги сначала переименовываются, затем копируются данные из backup.

cd ~/CODE/box3
compose.sh stop inference
compose.sh stop extended-inference

backup_root=/data/backups/<backup_id>
compose_data=/data/compose-data2

mv "$compose_data/converted" "$compose_data/converted.broken-$(date +%F-%H%M)"
mv "$compose_data/models-registry" \
  "$compose_data/models-registry.broken-$(date +%F-%H%M)"
rsync -a --numeric-ids "$backup_root/compose-data/converted/" \
  "$compose_data/converted/"
rsync -a --numeric-ids "$backup_root/compose-data/models-registry/" \
  "$compose_data/models-registry/"

compose.sh start inference
compose.sh start extended-inference

Контроль после запуска:

  • контейнеры inf-nri-inference, inf-load-balancer, svr-models-registry, inf-mediaserver находятся в состоянии Up;
  • в логах нет повторяющихся ошибок загрузки моделей и категорий;
  • тестовая камера или ранее настроенный сценарий запускается без ошибки отсутствующей модели;
  • при использовании Guardant лицензия подтверждается в логах inf-guardant-control-center.

3.2.7. Восстановление лицензии и host-настроек

При потере сервера или очистке Guardant runtime сначала восстановить ${COMPOSE_DATA}/guardant, если каталог был включён в резервную копию. Если активация всё равно не подтверждается, выполнить новую оффлайн-активацию по процедуре И2; старый request.request для нового состояния сервера не используется.

Host-настройки восстанавливаются до запуска контура:

sudo cp /data/backups/<backup_id>/daemon.json /etc/docker/daemon.json
sudo cp /data/backups/<backup_id>/fstab /etc/fstab
sudo cp /data/backups/<backup_id>/box-restart.service \
  /etc/systemd/system/box-restart.service
sudo systemctl daemon-reload
sudo systemctl enable box-restart.service

После восстановления проверить nvidia-smi, Docker runtime, tmpfs-mонты и доступность systemd-unit автозапуска.

3.2.8. Контроль успешности восстановления

Контроль Команда/действие Ожидаемый результат
Compose-домены cd ~/CODE/box3 && compose.sh status all Критичные сервисы Up; нет циклических рестартов.
Web API curl -fsS http://localhost/api/base/ping/ Возвращается успешный ответ gateway.
UI Открыть /login в целевом контуре Форма входа загружается, пользователь может авторизоваться.
PostgreSQL docker logs <postgres_container> --tail 100 Нет ошибок восстановления, прав доступа и повреждения WAL.
ClickHouse Логи ClickHouse и выборочная проверка событий/витрин Таблицы доступны, запросы не возвращают ошибки файлов данных.
MinIO/DTS Проверка открытия файла отчёта, изображения события или ассета Объекты доступны через штатные /api/s3/* маршруты.
Kafka Логи inf-kafka, ASUTP Kafka и потребителей Топики доступны, потребители не падают из-за отсутствия брокера.
Sandbox cd ~/CODE/node-red-sandbox && docker compose ps Контейнеры sandbox Up, iframe /sandbox/ открывается.
Инференс Логи inf-nri-inference, inf-load-balancer, inf-mediaserver Нет ошибок модели, лицензии, GPU runtime и IPC.
Контрольные суммы sha256sum -c <backup_id>.sha256 Использованная копия не повреждена.

3.2.9. Действия при ошибках восстановления

Ошибка Действие администратора
gzip -t или sha256sum -c завершается ошибкой Не использовать копию; выбрать предыдущий backup_id, сохранить повреждённый архив для расследования.
/pg-backup.sh restore вернул false Не запускать прикладной сервис; проверить доступность целевого PostgreSQL, права пользователя, выбранный архив и свободное место; повторить на тестовой БД или эскалировать.
PostgreSQL стартует, но приложение падает на миграциях Проверить соответствие версии ~/CODE и БД; при несовместимости восстановить код из того же backup_id.
ClickHouse или MinIO не стартуют после файлового restore Убедиться, что копия сделана на остановленном контуре; восстановить весь набор связанных каталогов из одного backup_id.
После restore нет событий, отчётов или файлов Проверить, что восстановлены не только PostgreSQL, но и MinIO/DTS, ClickHouse и файловые каталоги событий/отчётов.
Нет доступа в UI после восстановления st-auth Проверить st-auth, st-access, ui-rest-to-gprc, JWT-настройки и актуальность пользователей/ролей в восстановленной БД.
Инференс не поднимается после восстановления моделей Проверить права каталогов, наличие converted и models-registry, Guardant, GPU runtime и логи загрузки моделей.
Не хватает места для восстановления Остановить восстановление, сохранить текущие каталоги, расширить диск или перенести backup на другой volume; не удалять БД и MinIO без отдельной копии.

Если восстановление из последней пригодной копии не возвращает контур в работоспособное состояние, администратор эскалирует инцидент ответственному DevOps/VizorLabs. В обращении указываются контур, дата, backup_id, перечень выполненных команд, вывод compose.sh status all, проблемные строки логов и границы потерянных данных. Чувствительные значения из .env, дампов БД и лицензионных файлов в обращение не включаются.