Files
psql_tasks/move_psql02.md
T
2026-07-21 00:51:54 +08:00

7.4 KiB

Главная причина всех ваших ошибок при заливке данных — включённые триггеры и внешние ключи (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. Создаём полный дамп схемы и данных

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, триггеры). На его основе мы разделим восстановление на этапы.

pg_restore -l /opt/pg_dumps/edemo_ehd1_full.dump > /opt/pg_dumps/db.list

Шаг 1.3. Разделяем db.list на 3 части

Сделайте 3 копии файла db.list:

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.
  1. step2_data.list — Оставьте только:
  • Строки вида TABLE DATA (само наполнение).
  • Всё остальное удалите или закомментируйте.
  1. 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 файла на целевой сервер.

Убедитесь, что базовая БД создана на целевом сервере:

CREATE DATABASE edemo_ehd1;


Шаг 2.1. Создаём структуру (Pre-Data)

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

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).

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 и включает триггеры для новых операций.

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. Финальный шаг (Анализ БД)

После завершения восстановления обязательно обновите статистику планировщика запросов:

psql -h localhost -p 5432 -U postgres -d edemo_ehd1 -c "VACUUM ANALYZE;"