getpgdata: подробная документация переноса данных в новую БД (history + data/README)

This commit is contained in:
naeel
2026-08-18 22:20:46 +04:00
parent 0b2d7ac990
commit b60f3313a5
2 changed files with 138 additions and 0 deletions
+38
View File
@@ -0,0 +1,38 @@
# data/ — дамп данных прежней БД
Здесь сохранены данные, выгруженные из **прежней** PostgreSQL (инстанс
`postgresqlk8s-master.60bdf3e3-...`, БД `ipwhitelist`), до переноса в новую
(инстанс `a5e9d24f`).
## Файлы
| Файл | Таблица | Строк | Описание |
|---|---|---|---|
| `companies.json` | companies | 9 | метаданные компаний (id, client_id, name, custom_limit, created_at, updated_at) |
| `whitelist_entries.json` | whitelist_entries | 20 | записи белого списка (IP, comment, кто создал/изменил/удалил, даты) |
| `audit_log.json` | audit_log | 39 | журнал аудита (user_email, company_id, action, old/new_value, entry_id, created_at) |
| `_migrations.json` | _migrations | 2 | применённые миграции |
| `import.sql` | — | 84 строки | готовый SQL-скрипт вставки (companies → entries → audit + sequence) |
Формат каждого `.json` — ответ `POST /api/sql`:
```json
{ "ok": true, "fields": [...], "rows": [...], "rowCount": N }
```
## Почему нет session.json
Таблица `session` (1147 строк) — временные пользовательские сессии входа
(`connect-pg-simple`). Для переноса белых списков не нужна и не переносится —
в новой БД сессии создаются заново. Дамп `session.json` был обрезан и удалён.
## import.sql
Генерируется из `*.json` и содержит:
- `BEGIN; ... COMMIT;` — транзакция
- INSERT для `companies` (с явными id, `ON CONFLICT (id) DO NOTHING`)
- INSERT для `whitelist_entries` (id + company_id — ссылки сохранены)
- INSERT для `audit_log`
- `SELECT setval(...)` — сброс sequence на MAX(id)
**Важно:** `/api/sql` выполняет ОДИН statement за вызов, поэтому `import.sql` целиком
никак не выполнить одним запросом. Вставка делалась клиентом по одному INSERT.
+100
View File
@@ -141,3 +141,103 @@ PostgreSQL (тот же realm k8s). Доступ к новой БД — чере
**Проверено:** `node -c server.js` OK; локально: пустой SQL → 400; SELECT → идёт в БД;
`INSERT` без `WRITE_SQL` → 403 (до попытки подключения); `WRITE_SQL=1` + мульти-statement →
берётся только первый; процесс проверки остановлен.
## 8. Перенос данных из прежней БД в новую (60bdf3e3 → a5e9d24f)
**Цель:** перенести белые списки (IP, кто создал, когда) и связанные данные в **новую**
PostgreSQL (инстанс `a5e9d24f`), тот же realm k8s. Доступ к новой БД — через Keycloak,
автоматизировать нельзя → перенос выполнен через `getpgdata` + `POST /api/sql`.
### 8.1 Выгрузка данных из прежней БД
Пока приложение было подключено к прежней БД (`60bdf3e3`), все таблицы выгружены через
`/api/sql` (SELECT * ORDER BY id) и **сохранены в репо** в `data/*.json`:
| Файл | Таблица | Строк | Статус |
|---|---|---|---|
| `data/companies.json` | companies | 9 | полный, валиден |
| `data/whitelist_entries.json` | whitelist_entries | 20 | полный, валиден |
| `data/audit_log.json` | audit_log | 39 | полный, валиден |
| `data/_migrations.json` | _migrations | 2 | полный, валиден |
| session | session | 1147 | исключён (битый дамп, не нужен для переноса) |
Сессии намеренно НЕ переносятся: это временные пользовательские сессии входа
(`connect-pg-simple`), в новой БД они создаются заново.
Коммиты: данные `~`, генератор `data/import.sql` (коммит `0b2d7ac`).
⚠️ **Урок (зафиксирован в памяти):** нужно было выгрузить ВСЕ таблицы до смены кредов.
Первая выгрузка сохранила только `whitelist_entries`; `companies`/`audit_log` пришлось
догонять после временного возврата кредов на прежнюю БД.
### 8.2 Переключение на новую БД
В jsonEnv Nubes (`modify`) заданы креды новой ПГ + `WRITE_SQL=1`:
```json
{
"DB_HOST": "postgresqlk8s-master.a5e9d24f-0b5d-4196-8903-7ed60f6e6557.svc.cluster.local",
"DB_PORT": "5432",
"DB_NAME": "ipwhitelist",
"DB_USER": "super",
"DB_PASS": "<пароль новой ПГ>",
"DB_SSLMODE": "disable",
"WRITE_SQL": "1",
"PORT": "3000"
}
```
После `modify` проверено: `GET /` показывает host новой ПГ; `CREATE TEMP TABLE` → 200
(запись разрешена).
### 8.3 Проблема: несоответствие id компаний
В новой БД **изначально уже были компании** под другими id (типовая схема), поэтому при
прямой вставке по старым id возникли конфликты:
- Вставка с явным id: `WZ03709`(id=23) упал — duplicate key по `client_id` (в новой БД
`WZ03709` уже был под id=2)
- `WZ01112` и `WZ03709` оказались на неверных id (1 и 2 вместо 2 и 23)
- `WZ01325` (должен быть id=1) — вообще отсутствовал
**Причина:** уникальный индекс `companies_client_id_key` (client_id), id в новой БД не
совпадали со старой.
**Решение (безопасно, т.к. записи/аудит в новой БД были пусты и FK на companies отсутствуют):**
1. `DELETE FROM companies WHERE client_id IN ('WZ01112','WZ03709')` — убрать с неверных id
2. Вставить заново под правильные id: id=1→WZ01325, id=2→WZ01112, id=23→WZ03709
3. Восстановить `custom_limit` и даты для этих 3 строк из дампа (первая вставка ставила `NOW()`)
После этого маппинг id компаний новой БД **полностью совпал** со старой.
### 8.4 Вставка данных через /api/sql
Так как `/api/sql` выполняет **один statement** за вызов, INSERT отправлены по одному
стейтменту (клиент на Python):
1. `companies` — 9 вставок (с явными id, `ON CONFLICT (id) DO NOTHING`)
2. `whitelist_entries` — 20 вставок (id, company_id, value_cidr, comment, created_by,
created_at, updated_by, updated_at, deleted_by, deleted_at)
3. `audit_log` — 39 вставок
4. `SELECT setval(...)` — сброс sequence для трёх таблиц на MAX(id)
### 8.5 Проверка целостности и соответствия
После переноса выполнена **посимвольная сверка** новой БД против дампа старой:
| Таблица | Строк old/new | missing | extra | diffs | Результат |
|---|---|---|---|---|---|
| whitelist_entries | 20/20 | 0 | 0 | 0 | **MATCH** |
| audit_log | 39/39 | 0 | 0 | 0 | **MATCH** |
| companies | 9/9 | 0 | 0 | 0 (после фикса) | **MATCH** |
- `orphan` (записи без компании): **0** — все связи верны
- sequences: companies→368, whitelist_entries→20, audit_log→39
### 8.6 Итоговое состояние новой БД
- companies = 9
- whitelist_entries = 20 (из них активных 12, удалённых 8 — перенесены с deleted_at)
- audit_log = 39
- Данные идентичны прежней БД.
**Активные белые списки (12):** WZ02425 (2), WZ02727 (6), WZ03656 (2), WZ01112 (8.8.8.8).