Как выполнить резервное копирование и восстановление базы 1С на PostgreSQL без ошибок mvarchar и остановки кластера?

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

Администрирование баз данных 1С на СУБД PostgreSQL имеет ряд важных особенностей, связанных со спецификой платформы «1С:Предприятие». Одной из наиболее частых проблем, с которой сталкиваются системные администраторы и разработчики при попытке автоматизировать восстановление баз из логических дампов (созданных через pg_dump), является ошибка отсутствия типов данных: «тип public.mvarchar не существует».

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

Почему возникает ошибка public.mvarchar при восстановлении?

Для обеспечения совместимости поведения PostgreSQL с СУБД MS SQL Server (в части сравнения строк, обработки концевых пробелов и работы с регистром) компания 1С совместно с разработчиками Postgres Pro использует специальное расширение СУБД, добавляющее типы данных mchar и mvarchar. Эти типы разворачиваются внутри схемы public вашей базы данных при её первом создании средствами платформы 1С.

Когда мы пытаемся сделать выгрузку базы через стандартную утилиту СУБД со специальным ключом очистки:

pg_dump.exe --clean --format=plain ...

утилита генерирует в начале SQL-файла команды удаления существующих объектов (таких как DROP TABLE, DROP VIEW, а также DROP TYPE и DROP FUNCTION), чтобы перед импортом полностью очистить целевую базу. При попытке выполнить этот сценарий в одной транзакции (с ключом --single-transaction) или при строгой обработке ошибок (ON_ERROR_STOP=on) СУБД выдает ошибку:

тип "public.mvarchar" не существует (или блокирует его удаление, так как на него завязаны другие системные функции расширения).

Попытки использовать ключ --if-exists спасают не во всех конфигурациях баз, а игнорирование ошибок (отключение строгого режима) приводит к тому, что скрипт восстановления завершается со статусом ошибки (код возврата 1), что делает невозможным качественный автоматический контроль резервного копирования в скриптах PowerShell, Bash или специализированных программах (например, в Обновляторе 1С).

Удаление и полное пересоздание базы в СУБД перед импортом тоже вызывает проблему: кластер 1С «держит» соединения с базой данных, блокируя выполнение команды DROP DATABASE на стороне PostgreSQL.

---

Метод рокировки: наиболее безопасный алгоритм восстановления баз 1С

Для решения этой проблемы разработана и успешно применяется профессиональная схема восстановления «на лету» через временную базу данных. Её главное преимущество — высокая отказоустойчивость. Если в процессе импорта дампа произойдет какая-либо ошибка (например, повредится файл архива или отключится питание), исходная рабочая база никак не пострадает и продолжит функционировать. Пользователи не потеряют доступ к старым данным в случае аварии при восстановлении.

Рассмотрим по шагам этот алгоритм.

Шаг 1. Создание резервной копии (выгрузка дампа)

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


"C:\Program Files\PostgreSQL\bin\pg_dump.exe" --quote-all-identifiers --format=plain --dbname=postgresql://"USER":"PASSWORD"@"HOST:PORT"/"BASE1C" --file="C:\Backup\backup.sql"

Шаг 2. Создание чистой временной базы данных

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


"C:\Program Files\PostgreSQL\bin\createdb.exe" --encoding=utf8 --template=template1 --username="USER" --host="HOST" --port=PORT temp_restore

Шаг 3. Загрузка дампа во временную базу

Разворачиваем наш SQL-файл резервной копии во вновь созданную базу temp_restore. Так как база была абсолютно пустой, никаких конфликтов со старыми таблицами или типами данных mvarchar гарантированно не возникнет:


"C:\Program Files\PostgreSQL\bin\psql.exe" --single-transaction --echo-errors --quiet --set="ON_ERROR_STOP=on" --file="C:\Backup\backup.sql" --dbname=postgresql://"USER":"PASSWORD"@"HOST:PORT"/"temp_restore"

Если на данном шаге возникнет ошибка импорта, процесс прервется, но наша основная рабочая база BASE1C останется целой и невредимой.

Шаг 4. Блокировка соединений и подготовка кластера 1С

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

  1. Устанавливаем блокировку начала новых сеансов в свойствах информационной базы 1С.
  2. Блокируем выполнение регламентных и фоновых заданий.
  3. Принудительно завершаем сеансы всех работающих пользователей через свойства ИБ в консоли СУБД или кластера.
  4. Важный шаг: В свойствах информационной базы внутри кластера 1С временно очищаем поле «Имя базы данных в СУБД» (или меняем его на несуществующее). Это заставит кластер 1С отпустить все открытые транзакции и физические сетевые соединения (пул соединений) к нашей целевой базе BASE1C в PostgreSQL.

Шаг 5. Рокировка (переименование) баз данных на стороне СУБД

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


"C:\Program Files\PostgreSQL\bin\psql.exe" --dbname=postgresql://"USER":"PASSWORD"@"HOST:PORT"/"template1" --command="ALTER DATABASE BASE1C RENAME TO BASE1C_OLD;"

Затем переименовываем нашу временную базу temp_restore, в которую мы только что успешно залили бэкап, в имя основной рабочей базы:


"C:\Program Files\PostgreSQL\bin\psql.exe" --dbname=postgresql://"USER":"PASSWORD"@"HOST:PORT"/"template1" --command="ALTER DATABASE temp_restore RENAME TO BASE1C;"

Шаг 6. Возврат настроек кластера 1С и запуск пользователей

После успешной рокировки возвращаем настройки в кластере 1С в исходное состояние:

  1. Прописываем обратно имя базы данных BASE1C в свойствах информационной базы в консоли кластера 1С.
  2. Снимаем блокировку сеансов и регламентных заданий.
  3. Разрешаем пользователям вход. Система запущена на восстановленной копии базы!

Шаг 7. Удаление старой версии базы данных

Убедившись, что пользователи успешно заходят и работают в восстановленной базе данных, мы можем окончательно удалить старую копию базы СУБД (бывшую рабочую базу, переименованную в BASE1C_OLD) для освобождения дискового пространства:


"C:\Program Files\PostgreSQL\bin\dropdb.exe" --username="USER" --host="HOST" --port=PORT BASE1C_OLD

---

Оптимизация сброса соединений средствами PostgreSQL

Процедуру из Шага 4 по высвобождению базы в кластере 1С можно значительно ускорить и упростить, выполнив принудительный сброс соединений напрямую на уровне СУБД PostgreSQL. Для этого выполним следующий SQL-запрос под учетной записью суперпользователя СУБД:


-- Запрещаем новые подключения к рабочей базе данных
ALTER DATABASE BASE1C CONNECTION LIMIT 0;

-- Принудительно разрываем все существующие активные сессии
SELECT pg_terminate_backend(pid) 
FROM pg_stat_activity 
WHERE datname = 'BASE1C' AND pid <> pg_backend_pid();

После выполнения этих команд база данных мгновенно освобождается от блокировок со стороны сервера приложений 1С, что позволяет сразу же запустить команды переименования баз (Шаг 5).

---

Важная дискуссия: pg_dump против физического резервного копирования

В среде администраторов баз данных 1С часто ведется спор о терминологии и применимости утилиты pg_dump. Важно понимать разницу между терминами.

Логический дамп (выгрузка) — это текстовый (или сжатый) файл, содержащий инструкции на языке SQL для воссоздания структуры таблиц и заполнения их данными (команды CREATE TABLE, INSERT и т.д.). Именно это делает утилита pg_dump. По своей сути это близко к выгрузке информационной базы 1С в файл .dt, но выполняется на уровне СУБД.

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

Ограничения pg_dump при работе с 1С:

Для крупных и высоконагруженных промышленных баз 1С на PostgreSQL рекомендуется использовать инструменты физического резервного копирования, такие как утилита pg_probackup или связка утилиты pg_basebackup с непрерывным архивированием журналов предзаписи (WAL).

Тем не менее, для небольших баз данных, а также для создания гарантированной "страховочной" точки восстановления непосредственно перед процедурой обновления конфигураций 1С (как это делает инструмент "Обновлятор 1С"), логические дампы через pg_dump по-прежнему остаются отличным, простым и очень надежным инструментом.

← На главную