diff --git a/move_psql02.md b/move_psql02.md new file mode 100644 index 0000000..00665a1 --- /dev/null +++ b/move_psql02.md @@ -0,0 +1,161 @@ +Главная причина всех ваших ошибок при заливке данных — **включённые триггеры и внешние ключи (Foreign Keys)** в момент выполнения `COPY`. + +Из логов видно: + +1. Таблицы заполняются параллельно или в произвольном порядке. +2. Срабатывает триггер (например, `TrgAddBarcodePairOnInsert`), который пытается делать `INSERT` в таблицу `BarcodeOldBarcodePair`, **до того** как сама эта таблица успела создаться или заполниться. +3. Триггеры вызывают функции, которые начинают параллельно обновлять одну и ту же справочную таблицу (в логе — `AccessGroupModels`), что приводит к **взаимным блокировкам (deadlock)**. +4. Включаются Foreign Key проверки до того, как загрузились родительские таблицы. + +Делить дамп на 10 отдельных файлов (отдельно функции, отдельно вьюхи) не требуется. Достаточно строго разделить процесс на **3 фазы**: **Схема без ключей/триггеров $\rightarrow$ Данные (с отключенными триггерами) $\rightarrow$ Индексы, ключи, триггеры и вьюхи.** + +Инструменты `pg_dump` и `pg_restore` в кастомном формате (`-Fc`) умеют делать это идеально с помощью **файла оглавления (List File)**. + +--- + +## Подготовка: Как заменить Tablespace + +Чтобы не фильтровать SQL через `sed`/`grep`, передавайте флаг `--no-tablespaces` в `pg_dump`. + +Если хотите сменить владельца объектов на того, кто восстанавливает дамп, используйте флаг `--no-owner`. + +--- + +## Этап 1. Создание дампов на `dc01-srv01` + +Делаем один полноценный дамп в кастомном бинарном формате (`-Fc`). Это даст нам гибкость при восстановлении — мы сможем восстанавливать объекты в любом порядке. + +### Шаг 1.1. Создаём полный дамп схемы и данных + +```bash +pg_dump -h localhost -p 5436 -U postgres -d edemo_ehd1 \ + -F c \ + --no-tablespaces \ + --no-owner \ + -f /opt/pg_dumps/edemo_ehd1_full.dump + +``` + +### Шаг 1.2. Генерируем файл оглавления (List file) + +Этот файл содержит полный список всех создаваемых объектов (таблицы, функции, индексы, FK, триггеры). На его основе мы разделим восстановление на этапы. + +```bash +pg_restore -l /opt/pg_dumps/edemo_ehd1_full.dump > /opt/pg_dumps/db.list + +``` + +### Шаг 1.3. Разделяем `db.list` на 3 части + +Сделайте 3 копии файла `db.list`: + +```bash +cp /opt/pg_dumps/db.list /opt/pg_dumps/step1_pre_data.list +cp /opt/pg_dumps/db.list /opt/pg_dumps/step2_data.list +cp /opt/pg_dumps/db.list /opt/pg_dumps/step3_post_data.list + +``` + +Отредактируйте эти файлы текстовым редактором (`nano` или `vim`): + +1. **`step1_pre_data.list`** — Оставьте только: +* `SCHEMA`, `EXTENSION`, `TYPE`, `SEQUENCE` +* `TABLE` (структуру) +* `FUNCTION` / `PROCEDURE` (они нужны, если столбцы используют дефолтные значения из функций) +* *Удалите или закомментируйте (знаком `;` в начале строки) все строки с `TABLE DATA`, `CONSTRAINT`, `FOREIGN KEY`, `INDEX`, `TRIGGER`, `VIEW`, `MATERIALIZED VIEW`.* + + +2. **`step2_data.list`** — Оставьте только: +* Строки вида `TABLE DATA` (само наполнение). +* *Всё остальное удалите или закомментируйте.* + + +3. **`step3_post_data.list`** — Оставьте всё, что создается **после** заливки данных: +* `PRIMARY KEY`, `UNIQUE`, `CONSTRAINT`, `FOREIGN KEY` +* `INDEX` +* `TRIGGER` +* `VIEW` и `MATERIALIZED VIEW` +* `RULE` +* *Удалите строки `TABLE DATA`, базовые `TABLE` и `SCHEMA`.* + + + +--- + +## Этап 2. Восстановление на `dc02-srv02` + +Перенесите файл дампа `edemo_ehd1_full.dump` и 3 созданных `.list` файла на целевой сервер. + +Убедитесь, что базовая БД создана на целевом сервере: + +```sql +CREATE DATABASE edemo_ehd1; + +``` + +--- + +### Шаг 2.1. Создаём структуру (Pre-Data) + +На этом этапе создаются только таблицы, типы и функции. Нет ни триггеров, ни внешних ключей. + +```bash +pg_restore -h localhost -p 5432 -U postgres -d edemo_ehd1 \ + --no-tablespaces \ + --no-owner \ + -L /opt/pg_dumps/step1_pre_data.list \ + /opt/pg_dumps/edemo_ehd1_full.dump + +``` + +--- + +### Шаг 2.2. Загружаем данные (Data) + +Самый критичный момент: используем параметр `--disable-triggers`. Он отключает срабатывание триггеров во время выполнения `COPY`, что полностью убирает ваши ошибки `deadlock` и ошибки отсутствия записей в смежных таблицах. + +> **Важно:** Флаг `--disable-triggers` работает только если восстановление идет от имени суперпользователя (`postgres`). + +```bash +pg_restore -h localhost -p 5432 -U postgres -d edemo_ehd1 \ + --no-tablespaces \ + --no-owner \ + --disable-triggers \ + -j 4 \ + -L /opt/pg_dumps/step2_data.list \ + /opt/pg_dumps/edemo_ehd1_full.dump + +``` + +*(Параметр `-j 4` запустит параллельную загрузку в 4 потока для ускорения. Так как триггеры и FK отключены, таблицы загружаются без дедлоков).* + +--- + +### Шаг 2.3. Создаём индексы, внешние ключи, триггеры и вьюхи (Post-Data) + +Теперь, когда все данные уже на месте, PostgreSQL построит индексы, навесит Foreign Key и включает триггеры для новых операций. + +```bash +pg_restore -h localhost -p 5432 -U postgres -d edemo_ehd1 \ + --no-tablespaces \ + --no-owner \ + -j 4 \ + -L /opt/pg_dumps/step3_post_data.list \ + /opt/pg_dumps/edemo_ehd1_full.dump + +``` + +*(Параметр `-j 4` здесь значительно ускорит построение индексов).* + +--- + +### Шаг 2.4. Финальный шаг (Анализ БД) + +После завершения восстановления обязательно обновите статистику планировщика запросов: + +```bash +psql -h localhost -p 5432 -U postgres -d edemo_ehd1 -c "VACUUM ANALYZE;" + +``` + +