Резервные копии и данные
> Кратко. Почти всё, что нельзя потерять, лежит в PostgreSQL: базы городов (вместе с фото нарядов) и UsersDB. Кроме баз копируют .env и переменные служб, каталог данных GeoServer и конфигурацию nginx. Для баз в репозитории API есть скрипт с проверкой и ротацией и задача планировщика к нему.
Что копировать
| Что | Где | Зачем | Можно ли восстановить без копии |
|---|---|---|---|
| Базы городов | PostgreSQL, список — TGID_CITY_DBS |
Сеть, расчёты, журналы, наряды и их фото (tgid_work_order_photo), отключения, комментарии, формы, телеметрия, сценарии, ключи встраивания и вебхуки |
Нет. Сеть можно переконвертировать из десктопа, но всё, что ввели в вебе, пропадёт |
| UsersDB | PostgreSQL, USERS_DB_NAME |
Пользователи, их права и города, журнал действий | Нет |
sprav |
PostgreSQL, SPRAV_DB_NAME |
Справочники расчёта | Частично: движок может читать CSV из sety/sprav |
.env API и веба, переменные служб NSSM |
каталоги API и веба; реестр Services\<служба>\Parameters |
Пароли баз, JWT_SECRET, хеш мастер-пароля, ключи ИИ и подложек, движок расчёта |
Нет: без JWT_SECRET все сессии и выданные ключи (API v2, MCP, ArcGIS) станут недействительны |
| Каталог данных GeoServer | на сервере GeoServer | Рабочие области городов, слои и SQL-представления, стили | Только вручную, долго |
| Конфигурация nginx | каталог nginx | Пути городов, проверка входа GeoServer, кеши | По образцам scripts/nginx/ в репозитории веба |
Функции тайлов martin и его config.yaml |
MARTIN_SQL_DIR, каталог martin |
Тайлы сети из PostGIS | Да: scripts/martin/build_martin_functions.py и build_martin_config.py |
| Статичные тайлы PMTiles | STATIC_TILES_DIR, по умолчанию files/static_tiles/<город> |
Здания на встраиваемой карте | Да: окно «Статичные слои» или scripts/ops/bake_static_tiles_all.py |
Что копировать не нужно:
- Redis — там очереди и статусы задач;
- хранилище готовых выгрузок (
FILE_STORAGE) — файлы живутFILE_JOBS_TTL, по умолчанию час; - кеш тайлов GeoServer (GWC) и nginx;
- каталог
files/kls,files/tabи шаблоны Word — они в репозитории API.
Копии баз и .env содержат персональные данные и секреты. Храните их с тем же ограничением доступа, что и сам
сервер — Персональные данные.
Скрипт копирования баз
scripts/ops/backup-city-dbs.ps1 в репозитории API:
- Для каждой базы из
-Databasesи для UsersDB делаетpg_dump -Fcв<BackupRoot>\daily\<дата>\<база>.dump. Пишет сначала во временный.part. - Проверяет файл: он не пустой, и
pg_restore --listчитает его оглавление, то есть файл не обрезан. Только после этого.partпереименовывается в.dump. - По воскресеньям копирует дневной каталог в
weekly\. ХранитKeepDailyдневных (7) иKeepWeeklyнедельных (4) копий, более старые удаляет. - С
-RestoreCheck <база>восстанавливает свежий дамп во временную базуtgid_restore_check. Сверяет число строкnodesиlinesobjс исходной (допуск 1 %) и удаляет временную базу. На время проверки нужно место на диске данных PostgreSQL. - Журнал —
<LogDir>\backup-<год-месяц>.log, итог —<BackupRoot>\last-backup.json. Код выхода 1 — была ошибка, её видно в планировщике.
Подключение скрипт берёт из .env API (DB_*, USERS_DB_*). Пароль передаётся только через переменную
PGPASSWORD на время вызова и в журнал не пишется.
Список баз. Без -Databases скрипт берёт базы городов из TGID_CITY_DBS в .env API (из одногородского
.env — DB_NAME) и добавляет UsersDB, поэтому новый город попадает в копию сам. Нет ни того ни другого — скрипт
останавливается с ошибкой. База из списка, которой нет на сервере, — ошибка (код выхода 1, в журнале
«ОШИБКА»), а не тихий пропуск. После первого запуска проверьте в last-backup.json, что у каждой базы статус ok.
Задача планировщика. scripts/ops/install-backup-task.ps1 (от администратора) регистрирует две задачи от SYSTEM:
- «TGID backup» — с понедельника по субботу в 02:30;
- «TGID backup restore check» — по воскресеньям в 02:30, копия плюс пробное восстановление одной базы
(
-RestoreCheck auto: базы из того же списка чередуются по номеру недели).
У задач предел 6 часов; если компьютер был выключен, задача запускается при первой возможности. Удалить задачи —
Unregister-ScheduledTask -TaskName 'TGID backup', 'TGID backup restore check'.
Скрипт копирует только базы. .env, переменные служб, каталог GeoServer и nginx копируйте отдельно, после
каждого их изменения.
Восстановление
- База города целиком: остановите API и воркеры (или закройте город в nginx), создайте пустую базу и выполните
pg_restore -d <база> <файл>.dump. Скрипт проверки восстанавливает с--no-owner --no-privileges. Для рабочей базы с ролями PostgreSQL (AUTH_BACKEND=pg,DB_ROLE_SWITCH) восстанавливайте с правами, иначе пользователи потеряют доступ. - После восстановления API сам доведёт схему: недостающие таблицы и функции веба появятся при запуске или в ближайший проход доводки (Несколько городов).
- UsersDB: после восстановления проверьте версию миграций (
alembic current): она должна совпадать с кодом API. - Одна таблица или запись: восстановите дамп во временную базу и перенесите нужное запросом. Не восстанавливайте поверх рабочей базы.
- Кеш тайлов GeoServer после восстановления базы города сбросьте, иначе карта покажет старую сеть до истечения кеша.
Копии для стендов
Отдельного скрипта создания копий в репозитории нет. Копию делают из свежего дампа: pg_restore в базу с
суффиксом _copy (almatygid_copy, usersdb_copy). Стенд запускают с .env.copy рядом с .env: в нём только
отличия — DB_NAME, USERS_DB_NAME, свой REDIS_DB.
На копии те же персональные данные, что на проде. Стенд с выключенным входом (AUTH_DISABLED=true) показывает их
любому, кто его откроет. Держите такие стенды во внутренней сети.
Для разработчика
- Новая таблица веба в базе города попадает в копию сама. Если она хранит файлы (как фото нарядов), учитывайте размер копии.
- Новый город — добавить базу в список копирования вместе с
TGID_CITY_DBS(Несколько городов).
