Разберем распространенную проблему, с которой сталкиваются администраторы при развертывании копии рабочей базы 1С на сервере PostgreSQL. При накате текстового дампа (сгенерированного через pg_dump) на новую чистую базу процесс завершается множеством критических ошибок. В консоль выводятся сообщения о том, что функции, индексы или системные таблицы уже существуют.
Типичный лог таких ошибок выглядит следующим образом:
psql:/var/archive/db_backup.sql:180: ОШИБКА: функция "datediff2" с аргументами таких типов уже существует
psql:/var/archive/db_backup.sql:10042906: ОШИБКА: создать уникальный индекс "paramsng_pkey" не удалось
DETAIL: Ключ (filename, partno)=(ibparams.inf, 0) дублируется.
psql:/var/archive/db_backup.sql:10277953: ОШИБКА: отношение "byname" уже существует
psql:/var/archive/db_backup.sql:10277960: ОШИБКА: отношение "byname_v8userpwdplcs" уже существует
Выясним причину такого поведения СУБД и платформы, а затем рассмотрим подробный и безопасный алгоритм создания копии базы.
Появление этих ошибок почти всегда вызвано одной из двух причин:
rphost немедленно подключается к PostgreSQL. Обнаружив пустую или частично заполненную базу, платформа 1С автоматически инициализирует служебную структуру: создает служебные функции (включая datediff2), таблицы конфигурации (paramsng), таблицы пользователей (v8users) и первичные индексы. Когда утилита psql параллельно доходит до команд создания этих же объектов из дампа, СУБД выдает ошибки о нарушении уникальности ключей и невозможности повторного создания таблиц.CREATE DATABASE копирует данные из системного шаблона template1. Если в эту шаблонную базу ранее по ошибке вносились изменения или накатывались расширения, все эти объекты автоматически копируются в любую вновь созданную базу данных, создавая коллизии при импорте бэкапа.Чтобы избежать блокировок и конфликтов структуры, разберем по шагам правильную последовательность действий.
Если процесс восстановления уже упал с ошибками, продолжать работу в этой же базе нельзя: в ней нарушена логическая целостность данных. Базу данных необходимо полностью пересоздать. Сначала сбросим все активные сеансы (включая возможные попытки подключения кластера 1С) и удалим базу:
SELECT pg_terminate_backend(pid)
FROM pg_stat_activity
WHERE datname = 'db_copy' AND pid <> pg_backend_pid();
DROP DATABASE db_copy;
Создадим новую базу данных, явно указав в качестве шаблона полностью пустой системный шаблон template0. Это гарантирует отсутствие любых посторонних объектов:
CREATE DATABASE db_copy WITH TEMPLATE template0 ENCODING 'UTF8';
Важно: на этом шаге категорически запрещено добавлять информационную базу в кластер серверов 1С. Связь между 1С и СУБД должна отсутствовать вплоть до полного завершения восстановления.
Запустим восстановление данных из резервной копии средствами PostgreSQL. Если используется текстовый дамп, передадим утилите psql флаг немедленной остановки при первой же ошибке, чтобы исключить скрытую порчу данных:
psql -U postgres -v ON_ERROR_STOP=1 -d db_copy -f /var/archive/db_backup.sql
Дожидаемся корректного завершения процесса без ошибок.
Только после того как утилита восстановления полностью отработала, переходим в консоль администрирования серверов 1С:Предприятия и регистрируем новую информационную базу.
db_copy, пользователя и пароль).Проанализируем используемый подход к созданию бэкапов. Выгрузка в текстовый SQL-файл (pg_dump | pigz > backup.sql.gz) имеет существенные недостатки для баз 1С:
psql работает строго в один поток, что для баз объемом в сотни гигабайт занимает много часов.Рекомендуется использовать кастомный бинарный формат (-Fc) или формат директории (-Fd). Посмотрим на пример команды создания резервной копии:
pg_dump -U postgres -Fc -Z 6 -f /var/archive/complex2020_dev.dump complex2020_dev
Восстановление из такого формата выполняется с помощью специализированной утилиты pg_restore, которая поддерживает многопоточность. Пример восстановления в 4 потока:
pg_restore -U postgres -d db_copy -j 4 --clean --if-exists /var/archive/complex2020_dev.dump
Параметры --clean и --if-exists удаляют объекты базы перед их созданием, что защищает от случайных конфликтов структуры, а параметр -j существенно ускоряет процесс развертывания.
Если необходимо создать копию базы на том же самом сервере PostgreSQL (например, для разработки или тестирования), нет необходимости тратить время на связку pg_dump и pg_restore. Можно использовать встроенный механизм создания базы по шаблону рабочей базы данных.
Разберем эту процедуру:
CREATE DATABASE db_copy WITH TEMPLATE complex2020_dev ENCODING 'UTF8';При таком подходе СУБД выполняет пофайловое копирование на уровне дисковой подсистемы, что происходит в разы быстрее полного цикла выгрузки и загрузки дампа.