7.4 KiB
Главная причина всех ваших ошибок при заливке данных — включённые триггеры и внешние ключи (Foreign Keys) в момент выполнения COPY.
Из логов видно:
- Таблицы заполняются параллельно или в произвольном порядке.
- Срабатывает триггер (например,
TrgAddBarcodePairOnInsert), который пытается делатьINSERTв таблицуBarcodeOldBarcodePair, до того как сама эта таблица успела создаться или заполниться. - Триггеры вызывают функции, которые начинают параллельно обновлять одну и ту же справочную таблицу (в логе —
AccessGroupModels), что приводит к взаимным блокировкам (deadlock). - Включаются 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):
step1_pre_data.list— Оставьте только:
SCHEMA,EXTENSION,TYPE,SEQUENCETABLE(структуру)FUNCTION/PROCEDURE(они нужны, если столбцы используют дефолтные значения из функций)- Удалите или закомментируйте (знаком
;в начале строки) все строки сTABLE DATA,CONSTRAINT,FOREIGN KEY,INDEX,TRIGGER,VIEW,MATERIALIZED VIEW.
step2_data.list— Оставьте только:
- Строки вида
TABLE DATA(само наполнение). - Всё остальное удалите или закомментируйте.
step3_post_data.list— Оставьте всё, что создается после заливки данных:
PRIMARY KEY,UNIQUE,CONSTRAINT,FOREIGN KEYINDEXTRIGGERVIEWиMATERIALIZED VIEWRULE- Удалите строки
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;"