Здравствуйте! При работе с 1С и PostgreSQL, особенно после обновлений платформы или СУБД, можно столкнуться с ситуацией, когда стандартная процедура восстановления базы из резервной копии с помощью утилиты pg_restore начинает выдавать ошибки. База при этом может даже восстановиться и работать, но предупреждения вызывают беспокойство и указывают на некорректный процесс.
В этой статье мы подробно разберем две распространенные ошибки, проанализируем их причины и предложим надежные способы их устранения.
Ситуация: при восстановлении базы данных в пустую базу PostgreSQL командой pg_restore появляются следующие предупреждения:
ERROR: function "datediff2" already exists with same argument types.ERROR: could not create unique index "params_pkey" DETAIL: Key (filename, partno)=(ibparams.inf, 0) is duplicated.Давайте выясним, почему это происходит и как это исправить.
Несмотря на то, что вы создаете пустую базу данных командами DROP DATABASE и CREATE DATABASE, ошибки все равно появляются. Это говорит о том, что база в момент восстановления не является "идеально" пустой или на процесс влияют внешние факторы. Рассмотрим каждую ошибку отдельно.
Ошибка 1: `function "datediff2" already exists`
Это предупреждение, как правило, не является критичным. Его причина кроется в том, что служебные функции, необходимые для работы 1С (например, datediff2), могут создаваться в нескольких местах:
template1). При установке PostgreSQL для 1С в этот шаблон могут добавляться специфические функции.В результате pg_restore пытается создать функцию, которая уже существует в только что созданной "пустой" базе, что и вызывает конфликт. База при этом остается работоспособной, так как нужная функция на месте.
Ошибка 2: `Key (filename, partno)=(ibparams.inf, 0) is duplicated`
Эта ошибка гораздо серьезнее. Она указывает на нарушение уникальности первичного ключа в служебной таблице params. Эта таблица используется платформой 1С для хранения внутренних параметров информационной базы.
Основная причина — активные подключения к базе со стороны кластера серверов 1С. Разберем этот процесс по шагам:
DROP DATABASE).CREATE DATABASE).public.params начальные служебные данные, в том числе и ту самую запись с ключом (filename, partno)=(ibparams.inf, 0).pg_restore, который, в свою очередь, пытается восстановить данные из бэкапа и вставить в таблицу public.params точно такую же запись.В итоге возникает конфликт — попытка вставить дублирующуюся запись в поле с уникальным ключом. Это и есть корень проблемы.
Чтобы гарантированно избежать обеих ошибок, необходимо разорвать связь между кластером 1С и базой данных на время проведения работ. Этот метод является наиболее корректным и надежным.
Пошаговая инструкция:
Отключите базу от кластера 1С.
Зайдите в консоль администрирования серверов 1С Предприятия. В дереве объектов найдите нужный кластер и в нем — информационную базу, которую собираетесь восстанавливать. Нажмите на ней правой кнопкой мыши и выберите "Удалить". Важно: в появившемся диалоге выберите опцию "Удалить информационную базу из списка", а не "Удалить базу данных". Это действие лишь уберет регистрацию ИБ в кластере, но не затронет саму базу данных в PostgreSQL.
Подождите несколько секунд.
Дайте кластеру время (10-15 секунд достаточно), чтобы гарантированно разорвать все активные соединения с базой данных.
Пересоздайте базу данных в PostgreSQL.
Теперь, когда к базе нет подключений, выполните удаление и создание базы через pgAdmin или из командной строки.
Выполните восстановление из бэкапа.
Запустите команду pg_restore. Поскольку к пустой базе никто не подключится и не запишет лишних данных, процесс пройдет без ошибок дублирования ключа.
"C:\Program Files\PostgreSQL\12.5-6.1C\bin\pg_restore.exe" --host "localhost" --port "5432" --username "XXX" --dbname "XXX" --no-password --role "postgres" --section pre-data --section data --section post-data --verbose "XXX"
Подключите базу обратно к кластеру 1С.
Вернитесь в консоль администрирования серверов 1С. Создайте новую информационную базу, указав те же параметры (имя, сервер СУБД, имя базы данных), что были ранее. Кластер подключится к уже восстановленной базе, и система будет готова к работе.
Если по каким-то причинам первый способ не подходит, можно использовать встроенную возможность утилиты pg_restore — ключ --clean. Этот ключ заставляет утилиту перед созданием каждого объекта из бэкапа (таблицы, функции и т.д.) сначала выполнить команду на его удаление (DROP).
Пример команды:
"C:\Program Files\PostgreSQL\12.5-6.1C\bin\pg_restore.exe" --host "localhost" --port "5432" --username "XXX" --dbname "XXX" --no-password --role "postgres" --clean --verbose "XXX"
Что нужно знать об этом способе:
datediff2.params быстрее, чем pg_restore выполнит ее очистку. Поэтому первый способ, с отключением базы от кластера, является более предпочтительным.В заключение, проанализировав ситуацию, мы видим, что корень проблемы кроется не в ошибках самой PostgreSQL или платформы 1С, а в нарушении правильной последовательности администрирования. Всегда отключайте информационную базу от кластера 1С перед выполнением низкоуровневых операций с базой данных, таких как восстановление из бэкапа. Это обеспечит чистоту процесса и избавит вас от подобных ошибок.