Как восстановить базу 1С на PostgreSQL из дампа, полученного с помощью pgAdmin4?

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

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

Представьте ситуацию: вы создали резервную копию (дамп) работающей базы 1С с PostgreSQL, используя pgAdmin4. При попытке восстановления этого дампа на другом сервере, где версии 1С (например, 8.3.15.1565) и PostgreSQL (PostgresPro_1C_9.6.8_64bit_1C) казались идентичными, возникли многочисленные ошибки. После восстановления, попытка входа в базу из 1С также завершается неудачей с различными сообщениями об ошибках.

Основные ошибки, возникающие при восстановлении

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

  1. Ошибки, связанные с операторами и классами операторов:
    • pg_restore: error: could not execute query: ОШИБКА: оператор не существует: public.mchar public.> public.mchar Command was: ALTER OPERATOR public.> (public.mchar, public.mchar) OWNER TO postgres;
    • pg_restore: error: could not execute query: ОШИБКА: класс операторов "public.mvarchar_case_ops" для метода доступа "btree" не существует Command was: ALTER OPERATOR CLASS public.mvarchar_case_ops USING btree OWNER TO postgres;
    • Эти сообщения указывают на то, что PostgreSQL не может найти или корректно интерпретировать определения операторов (например, для сравнения типов mchar и mvarchar) и их классов, которые создаются платформой 1С. Это часто связано с использованием специализированной сборки PostgreSQL (PostgresPro 1C), которая содержит расширения для работы с этими типами данных.

  2. Ошибки при создании индексов из-за отсутствия классов операторов:
    • pg_restore: error: could not execute query: ОШИБКА: для типа данных public.mvarchar не определён класс операторов по умолчанию для метода доступа "btree" HINT: Вы должны указать класс операторов для индекса или определить класс операторов по умолчанию для этого типа данных. Command was: CREATE UNIQUE INDEX _acc48_7 ON public._acc48 USING btree (_fld887, _parentidrref, _orderfield, _idrref);
    • Если классы операторов, необходимые для индексации специфических типов данных 1С (таких как mvarchar), не были корректно созданы или распознаны, то попытка создания индексов завершится ошибкой.

  3. Ошибки "тип уже существует" при восстановлении в чистую базу, созданную 1С:
    • pg_restore: error: could not execute query: ОШИБКА: тип "mchar" уже существует Command was: CREATE TYPE public.mchar;
    • pg_restore: error: could not execute query: ОШИБКА: приведение типа public.mvarchar к типу public.mchar уже существует Command was: CREATE CAST (public.mvarchar AS public.mchar) WITH FUNCTION public.mvarchar_mchar(public.mvarchar, integer, boolean) AS IMPLICIT;
    • Если мы сначала создаем пустую базу из 1С (через консоль кластера 1С), а затем пытаемся восстановить в неё дамп, PostgreSQL может жаловаться на то, что типы данных (mchar, mvarchar) или приведения типов уже существуют. Это происходит потому, что 1С при создании новой базы инициализирует базовую структуру, включая эти специфические типы и связанные с ними объекты.

  4. Ошибки, связанные с синтаксисом определения операторов (FUNCTION vs PROCEDURE):
    • pg_restore: ПРЕДУПРЕЖДЕНИЕ: атрибут оператора "function" не распознан pg_restore: error: could not execute query: ОШИБКА: должна быть указана процедура оператора Command was: CREATE OPERATOR public.== ( FUNCTION = public.isfulleq_name, LEFTARG = name, RIGHTARG = name, COMMUTATOR = OPERATOR(public.==), HASHES, RESTRICT = eqsel, JOIN = eqjoinsel );
    • Это одна из ключевых ошибок, указывающая на различие в синтаксисе или интерпретации определения операторов между версиями или сборками PostgreSQL. Некоторые версии могут ожидать ключевое слово PROCEDURE вместо FUNCTION при указании функции-реализации оператора.

  5. Ошибки при входе в 1С:
    • Error: operator does not exist: mvarchar = unknown
    • Ошибка при выполнении операций с информационной базой Запись не найдена в менеджере имен баз данных.
    • Эти ошибки в самой платформе 1С указывают на то, что база данных либо не была восстановлена корректно, либо 1С не может найти необходимые объекты в базе для установления соединения и начала работы.

Причина возникновения проблем

Основная причина этих проблем кроется в использовании несовместимых утилит pg_dump и pg_restore, а также в различиях между стандартной сборкой PostgreSQL и специализированной сборкой PostgresPro 1C. Часто pgAdmin4 использует свой встроенный pg_dump, который может не быть полностью совместим с особенностями PostgresPro 1C. PostgresPro 1C включает патчи и специфические расширения (например, для типов mchar, mvarchar и связанных с ними операторов), которые стандартный pg_dump из другой версии или сборки может некорректно выгрузить, а pg_restore, соответственно, некорректно интерпретировать при восстановлении.

Таким образом, даже если версии 1С и PostgreSQL на первый взгляд совпадают (например, 9.6.8), принципиальное значение имеет именно сборка PostgreSQL (например, PostgresPro 1C) и соответствующие ей утилиты.

Решение 1: Корректировка SQL-дампа

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

  1. Получаем SQL-код дампа:

    Если у нас есть бинарный дамп, созданный pg_dump (или pgAdmin4), мы можем преобразовать его в текстовый SQL-файл с помощью утилиты pg_restore с опцией -f (или --file) и указанием выходного файла. Например:

    pg_restore -f output.sql your_backup.backup

    Если же дамп уже был создан как текстовый файл (например, .sql), этот шаг не требуется.

  2. Сравниваем с дампом пустой базы (при наличии):

    Если у нас есть возможность создать пустую базу 1С на целевом сервере и сделать с нее дамп (используя корректные утилиты pg_dump из PostgresPro 1C), мы можем сравнить структуру двух дампов (проблемного и рабочего пустого) с помощью утилиты diff или текстового редактора с функцией сравнения. Это позволит выявить ключевые различия в определениях объектов.

    В нашем случае, одно из критических различий заключалось в использовании ключевого слова FUNCTION вместо PROCEDURE при определении операторов.

  3. Выполняем массовую замену в SQL-дампе:

    Открываем полученный output.sql файл в текстовом редакторе (например, Notepad++, VS Code с поддержкой регулярных выражений) или используем утилиты командной строки (например, sed в Linux/WSL). Нам нужно найти все вхождения строки FUNCTION = public. и заменить их на PROCEDURE = public.. Автор решения выполнил эту замену около 150 раз.

    Пример изменений, которые могли быть обнаружены в логе сравнения:

    
    6c6  -- Dumped by pg_dump version 12.0
    21,50d20  FUNCTION = public.mchar_icase_gt,
    2117c2087  FUNCTION = public.mvarchar_icase_gt,
    2171c2141  FUNCTION = public.mchar_icase_lt,
    ... (много других строк, где FUNCTION меняется на PROCEDURE)
    

    Этот фрагмент демонстрирует, что в исходном дампе (слева) для определения операторов использовалось ключевое слово FUNCTION, тогда как в рабочем дампе (или в ожидаемом синтаксисе целевой сборки PostgreSQL) требовалось PROCEDURE. Массовая замена FUNCTION на PROCEDURE в строках, касающихся определений операторов, может решить эту проблему.

  4. Восстанавливаем базу из модифицированного SQL-файла:

    После внесения изменений в SQL-файл, мы можем попытаться восстановить базу данных с помощью утилиты psql, предварительно создав пустую базу данных (см. следующий раздел о создании из template0).

    psql -h localhost -p 5432 -U postgres -d new_1c_db < modified_output.sql

    Замените localhost, 5432, postgres и new_1c_db на соответствующие параметры вашего сервера и базы данных.

Решение 2: Восстановление в базу, созданную из template0

Это решение является более общим и часто помогает избежать ошибок "тип уже существует" или "функция уже существует" при восстановлении, а также может быть первым шагом перед применением корректировок дампа, описанных выше.

Суть проблемы: Когда мы создаем новую базу данных в PostgreSQL, она обычно копируется из шаблона template1. В template1 могут быть уже добавлены различные языки, процедуры или расширения, которые 1С или PostgresPro 1C устанавливают по умолчанию. Если наш дамп также содержит определения этих объектов, возникает конфликт "уже существует".

Решение: Создать новую базу данных на основе template0. template0 — это "чистый" шаблон, который гарантированно не содержит никаких пользовательских объектов, языков или расширений. Это дает нам максимально пустую базу данных для восстановления.

  1. Создаем пустую базу данных из template0:

    Подключаемся к серверу PostgreSQL (например, через psql) и создаем новую базу данных, явно указав шаблон template0. Мы также можем использовать утилиту createdb:

    createdb -h localhost -p 5432 -U postgres -T template0 new_1c_db

    Здесь:

    • -h localhost: адрес хоста PostgreSQL.
    • -p 5432: порт PostgreSQL.
    • -U postgres: пользователь PostgreSQL.
    • -T template0: ключевая опция, указывающая на использование чистого шаблона.
    • new_1c_db: имя новой базы данных для 1С.

    Вместо createdb также можно использовать SQL-команду:

    
    CREATE DATABASE new_1c_db WITH TEMPLATE = template0 ENCODING = 'UTF8' LC_COLLATE = 'ru_RU.UTF-8' LC_CTYPE = 'ru_RU.UTF-8';
    

    Убедитесь, что параметры ENCODING, LC_COLLATE и LC_CTYPE соответствуют настройкам исходной базы и рекомендациям 1С для вашей локали.

  2. Восстанавливаем дамп в созданную базу:

    После создания пустой базы из template0, мы можем использовать pg_restore для восстановления дампа.

    Если у вас бинарный дамп:

    pg_restore -h localhost -p 5432 -U postgres -d new_1c_db -v your_backup.backup

    Если у вас текстовый SQL-файл (возможно, уже модифицированный по Решению 1):

    psql -h localhost -p 5432 -U postgres -d new_1c_db < modified_output.sql

Общие рекомендации и лучшие практики

Чтобы минимизировать проблемы при восстановлении баз 1С на PostgreSQL, следуйте этим рекомендациям:

  1. Идентичность окружения:

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

  2. Использование утилит из одной сборки:

    Всегда используйте утилиты pg_dump и pg_restore, входящие в состав той же версии и сборки PostgreSQL (в данном случае PostgresPro 1C), с которой работала исходная база. Избегайте использования утилит из сторонних источников или из другого ПО (например, встроенного pg_dump в pgAdmin4, если он отличается от установленного PostgresPro 1C).

  3. Проверка работоспособности копии:

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

  4. Технологический журнал 1С и логи PostgreSQL:

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

  5. Пользователи PostgreSQL:

    Убедитесь, что на новом сервере созданы те же пользователи PostgreSQL, что и на старом, с теми же паролями и правами доступа, которые используются для подключения 1С к базе данных.

  6. Опция -a (--data-only) для pg_restore:

    В некоторых случаях, если структура базы данных (схема, типы, операторы) уже была создана 1С на целевом сервере, но данные отсутствуют, можно попробовать восстановить только данные из дампа, используя опцию -a или --data-only:

    pg_restore -h localhost -p 5432 -U postgres -d new_1c_db -a your_backup.backup

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

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

← На главную