From b60f3313a5f75a11cc256742427b69546ebdc117 Mon Sep 17 00:00:00 2001 From: naeel Date: Tue, 18 Aug 2026 22:20:46 +0400 Subject: [PATCH] =?UTF-8?q?getpgdata:=20=D0=BF=D0=BE=D0=B4=D1=80=D0=BE?= =?UTF-8?q?=D0=B1=D0=BD=D0=B0=D1=8F=20=D0=B4=D0=BE=D0=BA=D1=83=D0=BC=D0=B5?= =?UTF-8?q?=D0=BD=D1=82=D0=B0=D1=86=D0=B8=D1=8F=20=D0=BF=D0=B5=D1=80=D0=B5?= =?UTF-8?q?=D0=BD=D0=BE=D1=81=D0=B0=20=D0=B4=D0=B0=D0=BD=D0=BD=D1=8B=D1=85?= =?UTF-8?q?=20=D0=B2=20=D0=BD=D0=BE=D0=B2=D1=83=D1=8E=20=D0=91=D0=94=20(hi?= =?UTF-8?q?story=20+=20data/README)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- data/README.md | 38 ++++++++++++++++ history/2026-08-18.md | 100 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 138 insertions(+) create mode 100644 data/README.md diff --git a/data/README.md b/data/README.md new file mode 100644 index 0000000..f683574 --- /dev/null +++ b/data/README.md @@ -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. diff --git a/history/2026-08-18.md b/history/2026-08-18.md index 7d9ca66..404295c 100644 --- a/history/2026-08-18.md +++ b/history/2026-08-18.md @@ -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). +