Как исправить ошибки "function already exists" и "duplicated key" при восстановлении базы 1С на PostgreSQL?

Системный администратор 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

Здравствуйте! При работе с 1С и PostgreSQL, особенно после обновлений платформы или СУБД, можно столкнуться с ситуацией, когда стандартная процедура восстановления базы из резервной копии с помощью утилиты pg_restore начинает выдавать ошибки. База при этом может даже восстановиться и работать, но предупреждения вызывают беспокойство и указывают на некорректный процесс.

В этой статье мы подробно разберем две распространенные ошибки, проанализируем их причины и предложим надежные способы их устранения.

Ситуация: при восстановлении базы данных в пустую базу PostgreSQL командой pg_restore появляются следующие предупреждения:

  1. Ошибка создания функции: ERROR: function "datediff2" already exists with same argument types.
  2. Ошибка создания первичного ключа: 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), могут создаваться в нескольких местах:

В результате pg_restore пытается создать функцию, которая уже существует в только что созданной "пустой" базе, что и вызывает конфликт. База при этом остается работоспособной, так как нужная функция на месте.

Ошибка 2: `Key (filename, partno)=(ibparams.inf, 0) is duplicated`

Эта ошибка гораздо серьезнее. Она указывает на нарушение уникальности первичного ключа в служебной таблице params. Эта таблица используется платформой 1С для хранения внутренних параметров информационной базы.

Основная причина — активные подключения к базе со стороны кластера серверов 1С. Разберем этот процесс по шагам:

  1. Вы удаляете информационную базу из консоли PostgreSQL (DROP DATABASE).
  2. Вы тут же создаете новую, пустую базу с тем же именем (CREATE DATABASE).
  3. Кластер серверов 1С, который все еще "помнит" об этой базе, обнаруживает ее появление и немедленно устанавливает соединение.
  4. Установив соединение, служба 1С записывает в пустую таблицу public.params начальные служебные данные, в том числе и ту самую запись с ключом (filename, partno)=(ibparams.inf, 0).
  5. Сразу после этого вы запускаете pg_restore, который, в свою очередь, пытается восстановить данные из бэкапа и вставить в таблицу public.params точно такую же запись.

В итоге возникает конфликт — попытка вставить дублирующуюся запись в поле с уникальным ключом. Это и есть корень проблемы.

Решение 1: Правильная последовательность восстановления (рекомендуемый способ)

Чтобы гарантированно избежать обеих ошибок, необходимо разорвать связь между кластером 1С и базой данных на время проведения работ. Этот метод является наиболее корректным и надежным.

Пошаговая инструкция:

  1. Отключите базу от кластера 1С.

    Зайдите в консоль администрирования серверов 1С Предприятия. В дереве объектов найдите нужный кластер и в нем — информационную базу, которую собираетесь восстанавливать. Нажмите на ней правой кнопкой мыши и выберите "Удалить". Важно: в появившемся диалоге выберите опцию "Удалить информационную базу из списка", а не "Удалить базу данных". Это действие лишь уберет регистрацию ИБ в кластере, но не затронет саму базу данных в PostgreSQL.

  2. Подождите несколько секунд.

    Дайте кластеру время (10-15 секунд достаточно), чтобы гарантированно разорвать все активные соединения с базой данных.

  3. Пересоздайте базу данных в PostgreSQL.

    Теперь, когда к базе нет подключений, выполните удаление и создание базы через pgAdmin или из командной строки.

  4. Выполните восстановление из бэкапа.

    Запустите команду 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"
    
  5. Подключите базу обратно к кластеру 1С.

    Вернитесь в консоль администрирования серверов 1С. Создайте новую информационную базу, указав те же параметры (имя, сервер СУБД, имя базы данных), что были ранее. Кластер подключится к уже восстановленной базе, и система будет готова к работе.

Решение 2: Использование ключа --clean (альтернативный способ)

Если по каким-то причинам первый способ не подходит, можно использовать встроенную возможность утилиты 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"

Что нужно знать об этом способе:

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

← На главную