При администрировании крупных баз данных 1С:Предприятие на СУБД PostgreSQL системные администраторы часто сталкиваются с внезапным отказом штатных средств резервного копирования. Ошибка обычно проявляется при использовании стандартной утилиты pg_dump и сопровождается следующим аварийным сообщением:
pg_dump: Ошибка выгрузки таблицы "config": сбой в PQgetResult(). Сообщение об ошибке с сервера: Р?РЁР?Р'Р?Р?: invalid memory alloc request size 1174829507. Выполнялась команда: COPY public.config (filename, creation, modified, attributes, datasize, binarydata) TO stdout;
Эта проблема чаще всего затрагивает конфигурации с долгой историей развития, такие как «1С:Комплексная автоматизация 1.1» (КА), «1С:Управление производственным предприятием 1.3» (УПП), а также крупные отраслевые решения на их базе. Давайте подробно разберем технические причины этого сбоя и рассмотрим пошаговые сценарии его гарантированного устранения.
Для того чтобы понять природу возникновения этой ошибки, проанализируем структуру хранения метаданных в базах данных платформы 1С. Файл конфигурации 1С (расширение .cf) записывается в системную таблицу config в виде двоичных данных (тип данных bytea или BLOB). В таблице config за хранение самого файла конфигурации отвечает поле binarydata.
Когда конфигурация находится на поддержке с возможностью изменения, СУБД вынуждена хранить сразу несколько версий метаданных: основную конфигурацию и конфигурацию поставщика. Суммарный объем одной строки с конфигурацией поставщика в поле binarydata может легко превысить 500 Мегабайт.
При запуске резервного копирования через утилиту pg_dump происходит следующее:
pg_dump выполняет выгрузку данных таблицы через SQL-команду COPY ... TO stdout.bytea) в текстовом потоке резервной копии СУБД PostgreSQL производит экранирование (кодирование) бинарного поля в текстовый формат (hex-формат или octal). При этом кодировании каждый байт двоичных данных превращается в 2 байта текста (а с учетом управляющих символов объем может вырасти еще больше).palloc в исходном коде) не может превышать 1 Гигабайт (точнее, значение макроса MaxAllocSize, равное 0x3FFFFFFF байт или 1 073 741 823 байта).binarydata составляет, например, 550 Мегабайт, то при конвертации в текстовое представление СУБД пытается выделить буфер памяти размером более 1,1 Гигабайта.invalid memory alloc request size.Проанализируем практические способы обхода этого ограничения и выберем наиболее стабильные решения.
---
Наиболее изящным и безопасным способом решения проблемы без изменения структуры метаданных и конфигурации 1С является разделение процесса создания бэкапа на три независимых этапа. Мы исключим проблемную таблицу config из общего текстового дампа и выгрузим ее отдельно в "сыром" бинарном виде, который не требует перекодирования в текст и не вызывает переполнения буфера памяти.
Рассмотрим по шагам автоматизированный скрипт резервного копирования для операционной системы Linux:
#!/bin/bash
# Настройка переменных окружения
DB_NAME="firm_db"
BACKUP_DIR="/var/backups/1c"
DATE=$(date +%Y_%m_%d_%H%M)
# Шаг 1. Выгрузка основного дампа всей базы данных ЗА ИСКЛЮЧЕНИЕМ данных таблицы config
pg_dump -U postgres -F c -Z 9 -T public.config -f "${BACKUP_DIR}/${DB_NAME}_data_${DATE}.backup" "${DB_NAME}"
# Шаг 2. Выгрузка только структуры (схемы) таблицы config без самих данных
pg_dump -U postgres -t public.config -s -f "${BACKUP_DIR}/${DB_NAME}_config_schema_${DATE}.sql" "${DB_NAME}"
# Шаг 3. Прямая бинарная выгрузка данных таблицы config через механизм COPY WITH BINARY
psql -U postgres -d "${DB_NAME}" -c "COPY public.config TO '${BACKUP_DIR}/${DB_NAME}_config_data_${DATE}.bin' WITH BINARY;"
Проанализируем процесс восстановления такой резервной копии. При возникновении аварийной ситуации развертывание базы данных из трех полученных файлов необходимо выполнять в строго определенном порядке:
config):
pg_restore -U postgres -d firm_db /var/backups/1c/firm_db_data_YYYY_MM_DD_HHMM.backup
config из сохраненного SQL-файла схемы:
psql -U postgres -d firm_db -f /var/backups/1c/firm_db_config_schema_YYYY_MM_DD_HHMM.sql
psql -U postgres -d firm_db -c "COPY public.config FROM '/var/backups/1c/firm_db_config_data_YYYY_MM_DD_HHMM.bin' WITH BINARY;"
Важное предупреждение: Метод COPY ... WITH BINARY является платформозависимым. Настоятельно рекомендуем разворачивать полученный бинарный файл данных на СУБД аналогичной архитектуры (например, перенос с x64 на x64) и той же мажорной версии PostgreSQL во избежание несовместимости форматов хранения.
---
Если логическое резервное копирование через pg_dump продолжает вызывать трудности, имеет смысл полностью перевести контур резервного копирования на физический уровень. При физическом копировании СУБД работает непосредственно с файлами табличных пространств на диске (побайтное копирование страниц памяти) и не производит никаких высокоуровневых преобразований данных в текст. Ограничение в 1 ГБ памяти здесь не играет роли.
Для создания надежных инкрементных и полных физических бэкапов рекомендуется использовать специализированные утилиты:
Посмотрим на пример использования pg_basebackup для создания транзакционно согласованной физической копии:
pg_basebackup -h localhost -U postgres -D /var/backups/physical/base_backup_directory -F t -z -P
Этот метод гарантирует 100% стабильность создания архива вне зависимости от размера конфигурации 1С и объема отдельных полей СУБД.
---
Поскольку проблема с ограничением буфера памяти при выгрузке больших объектов (LOBs) в базах 1С хорошо известна отечественным разработчикам СУБД, в специализированных российских дистрибутивах PostgreSQL были внедрены встроенные параметры для обхода этой ошибки.
Если вы используете коммерческую версию Postgres Pro Enterprise (начиная с релиза 15.2.1 и старше), вы можете использовать специальный параметр enable_large_mem_buffers. Он расширяет максимально допустимый размер выделяемой памяти под текстовое представление объектов bytea до 2 Гигабайт.
Для активации возможности выгрузки больших конфигураций выполните следующую команду в консоли СУБД или добавьте параметр в файл конфигурации postgresql.conf:
ALTER SYSTEM SET enable_large_mem_buffers = on;
SELECT pg_reload_conf();
При использовании утилиты pg_dump из этого пакета обязательно передавайте специализированный флаг:
pg_dump -U postgres --enable-large-mem-buffers -F c -f /arc/my_db.backup my_db
Если ваша инфраструктура развернута на базе операционной системы Astra Linux с СУБД Tantor Special Edition, аналогичного результата можно добиться включением параметра enable_large_allocations:
# В файле postgresql.conf установите параметр:
enable_large_allocations = on
После перезапуска СУБД лимит на выделение памяти будет расширен, и стандартный бэкап через pg_dump пройдет без ошибок.
---
Если база данных находится на поддержке, но при этом активно дорабатывается программистами, СУБД вынуждена хранить внутри таблицы config избыточные данные поставщика (зачастую дублирующиеся). Если полностью снять конфигурацию с поддержки (перевести в статус "Конфигурация находится на поддержке с возможностью изменения" с полным удалением исходных файлов поставщика или полностью снять замок), размер таблицы config сократится практически в два раза.
Проанализируем, как правильно произвести эту операцию в Конфигураторе 1С:
config.VACUUM FULL config; в консоли PostgreSQL для очистки дискового пространства и дефрагментации таблицы.После проведения данной процедуры размер поля binarydata уменьшится до приемлемых 300-450 Мегабайт, и стандартная утилита pg_dump начнет отрабатывать в штатном режиме без ошибок выделения памяти.
---
Зачастую размер конфигурации раздувается из-за нерационального хранения двоичных данных непосредственно внутри метаданных 1С. Разработчики могут хранить в макетах भारी файлы, такие как:
Проанализируем конфигурацию на наличие "тяжелых" объектов метаданных. Откройте конфигурацию, перейдите в раздел Общие -> Общие макеты и просмотрите двоичные макеты. Удаление устаревших драйверов торгового оборудования, внешних компонент или перенос тяжелых инструкций во внешние файловые ресурсы позволят сократить размер файла конфигурации (.cf) ниже критической отметки в 500 Мегабайт. Как только чистый размер конфигурации уменьшится, СУБД PostgreSQL сможет успешно преобразовывать бинарное поле в текст при выгрузке резервной копии.