Как исправить ошибку PostgreSQL "unexpected out-of-memory" при выгрузке базы 1С в формат .dt?

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

При администрировании баз данных 1С на СУБД PostgreSQL системные администраторы часто сталкиваются с неприятной ситуацией: при попытке выполнить стандартную операцию «Выгрузить информационную базу» (создание файла .dt) процесс аварийно прерывается. На экране появляется системное сообщение: «Ошибка СУБД: ERROR: unexpected out-of-memory...» (в полной формулировке — unexpected out-of-memory situation during sort или unexpected out-of-memory situation in tuplestore).

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

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

Выясняем причину: программный баг tuplestore в PostgreSQL

Для того чтобы понять природу ошибки, обратимся к исходному коду СУБД PostgreSQL. В версиях семейства 9.3 (включая популярную сборку 9.3.4-1.1C), а также в ранних минорных релизах веток 9.4 и 9.5 присутствовал зарегистрированный разработчиками баг (Bug #13530).

Проблема кроется в модуле tuplestore.c, который отвечает за временное хранение кортежей данных при выполнении сортировки во внешней памяти. Когда СУБД понимает, что объем сортируемых данных превышает лимит, выделенный в оперативной памяти, запускается алгоритм масштабирования массивов адресации. Из-за некорректного математического расчета накладных расходов на адресацию указателей СУБД ошибочно считала, что доступная память полностью исчерпана (так называемое состояние LACKMEM). База данных аварийно прекращала выполнение тяжелого запроса с ошибкой «out-of-memory», хотя физически на сервере могло оставаться свободным огромное количество оперативной памяти.

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

Способ 1. Изменение параметра work_mem (Быстрое обходное решение)

Программная ошибка в модуле tuplestore наиболее часто проявляет себя, когда для сессий пользователей выделено небольшое количество рабочей памяти. За это отвечает параметр work_mem в конфигурационном файле СУБД. По умолчанию этот параметр может быть настроен всего на 4MB или 8MB. При обработке гигантских таблиц 1С этого объема не хватает, данные начинают сбрасываться на диск во временные файлы, активируя ошибочный код СУБД.

Для того чтобы обойти этот баг, увеличим объем оперативной памяти, выделяемой под каждую операцию сортировки:

  1. Найдем на сервере конфигурационный файл СУБД. Обычно он располагается по пути:
    /var/lib/pgsql/data/postgresql.conf (в ОС Linux) или в папке установки PostgreSQL в каталоге data (в ОС Windows).
  2. Откроем этот файл любым текстовым редактором с правами администратора.
  3. Найдем строку с параметром work_mem. По умолчанию она может быть закомментирована знаком #.
  4. Раскомментируем строку и установим новое увеличенное значение. Рекомендуется задать значение от 64MB до 256MB в зависимости от характеристик вашего сервера:

# Открываем postgresql.conf и правим параметр:
work_mem = 128MB

Важное предупреждение: Параметр work_mem выделяется под каждую отдельную операцию сортировки внутри каждого активного запроса. Если на сервере одновременно работает много пользователей, суммарное потребление памяти СУБД может резко вырасти. Не устанавливайте этот параметр в экстремально высокие значения (например, несколько гигабайт), иначе операционная система может принудительно завершить процесс PostgreSQL по нехватке реальной ОЗУ (работа механизма OOM Killer).

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

systemctl restart postgresql-9.3

Способ 2. Обновление версии PostgreSQL (Рекомендуемый и надежный метод)

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

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

Способ 3. Обслуживание СУБД и оптимизация базы данных 1С

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

Проведем обслуживание на стороне PostgreSQL. Подключимся к базе данных через консоль psql или утилиту pgAdmin и выполним команду полной очистки и обновления статистики:


-- Полная очистка таблиц от устаревших записей и обновление статистических данных
VACUUM FULL ANALYZE;

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

Также рекомендуется провести обслуживание средствами самой платформы 1С:

  1. Запустим информационную базу в режиме Конфигуратора в монопольном режиме.
  2. Перейдем в главное меню: Администрирование — Тестирование и исправление...
  3. Установим флажки напротив пунктов Реиндексация таблиц информационной базы и Проверка логической целостности информационной базы.
  4. Запустим процесс выполнения. Платформа пересоздаст индексы, что значительно ускорит выборку данных и уменьшит вероятность возникновения ошибок при экспорте в .dt.

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

← На главную