Как исправить ошибку «out of memory for query result» при работе 1С с PostgreSQL?

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

При эксплуатации связки 1С:Предприятие и PostgreSQL системные администраторы часто сталкиваются с ошибкой «out of memory for query result». Эта проблема особенно актуальна при построении тяжелых отчетов или выполнении объемных обменов данными. Проанализируем природу этой ошибки, выясним, почему она возникает даже при наличии свободной оперативной памяти на сервере, и разберем по шагам методы её решения.

Природа ошибки: кто виноват — сервер или клиент?

Первое, что нам необходимо понять: несмотря на то, что ошибка упоминает СУБД, она генерируется не ядром PostgreSQL, а клиентской библиотекой libpq. Эту библиотеку сервер приложений 1С (процесс rphost) использует для взаимодействия с базой данных. Разберем механизм взаимодействия подробнее:

  1. Сервер 1С отправляет SQL-запрос к PostgreSQL.
  2. СУБД обрабатывает запрос и подготавливает результат.
  3. Библиотека libpq на стороне сервера 1С пытается выделить в адресном пространстве процесса rphost непрерывный буфер памяти, чтобы принять весь объем данных от СУБД целиком.
  4. Если процесс rphost не может выделить такой объем памяти (из-за общего лимита или фрагментации), библиотека выдает ошибку «out of memory for query result».

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

Проблема 32-битной архитектуры сервера 1С

Проанализируем ситуацию, описанную в теме: используется 32-битный сервер 1С на 64-битной операционной системе Windows Server. Рассмотрим технические ограничения такой конфигурации:

Выясним, почему помогает перезагрузка служб. В процессе долгой работы память rphost подвергается фрагментации. Она становится похожа на «швейцарский сыр»: много мелких свободных участков, но ни одного цельного куска размером, скажем, в 500 МБ. После перезапуска память чиста, фрагментация нулевая, и тот же самый тяжелый отчет временно начинает проходить без ошибок.

Методы решения проблемы

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

1. Переход на 64-битный сервер 1С

Это стратегически верное и единственное надежное решение. 64-битный процесс rphost практически не ограничен в объеме используемой оперативной памяти (лимит измеряется терабайтами). Это позволяет выделять любые необходимые буферы под результаты запросов. Если ваша лицензия позволяет использовать 64-битную версию сервера, выполните переход в первую очередь.

2. Настройка параметров PostgreSQL

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

Обратим внимание на параметр work_mem. В исходном сообщении он был установлен в 256MB. Рассмотрим, почему это может быть опасно:

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

Также проверьте параметр cursor_tuple_fraction. Установка значения 1.0 может помочь оптимизировать планировщик на получение всего объема данных, что иногда положительно сказывается на стабильности передачи больших наборов строк.

3. Оптимизация количества рабочих процессов

Если переход на 64-битную версию временно невозможен, проанализируем настройки кластера 1С. Разберем возможность разделения нагрузки:

  1. Увеличьте количество рабочих процессов в консоли администрирования серверов 1С.
  2. Настройте параметр «Количество информационных баз на процесс» или «Количество соединений на процесс».
  3. Это позволит распределить пользователей по разным процессам rphost. Если один пользователь запустит «тяжелый» отчет и вызовет ошибку в своем процессе, это не затронет остальных и даст каждому процессу свой отдельный лимит в 3.5 ГБ.

4. Использование Технологического журнала для поиска «жадных» запросов

Чтобы понять, какой именно отчет или обработка вызывают ошибку, настроим Технологический журнал (ТЖ). Нам нужно отловить событие DBPOSTGRS. Создадим файл logcfg.xml следующего содержания:


<config xmlns="http://v8.1c.ru/7.4/puls/logcfg">
  <log location="C:\LOGS\POSTGRES" history="24">
    <event>
      <eq property="Name" value="DBPOSTGRS"/>
      <not>
        <eq property="Context" value=""/>
      </not>
    </event>
    <property name="All"/>
  </log>
</config>

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

5. Обновление версии СУБД

Версия PostgreSQL 9.4, упомянутая в обсуждении, является устаревшей. Рекомендуем рассмотреть переход на актуальные версии (12, 13 или выше), адаптированные для 1С (например, от Postgres Professional). В новых версиях значительно улучшена работа с памятью и оптимизированы механизмы очистки временных таблиц, что снижает вероятность возникновения ошибок переполнения буфера.

Резюме и рекомендации

Подведем итог нашему анализу. Ошибка «out of memory for query result» — это классический признак «упирания» в потолок 32-битной архитектуры.

Для быстрого решения:

Для окончательного решения:

  1. Перейдите на 64-битный сервер 1С:Предприятие.
  2. Обновите PostgreSQL до актуальной версии, поддерживаемой 1С.
  3. Проведите аудит кода наиболее тяжелых отчетов через Технологический журнал.

Помните, что настройка параметров shared_buffers или effective_cache_size влияет на производительность поиска данных, но почти не помогает при ошибке out of memory на стороне клиента, так как корень проблемы лежит в этапе передачи уже сформированного результата запроса в адресное пространство 1С.

← На главную