Как решить проблему взрывного роста временных файлов в PostgreSQL при закрытии месяца в 1С:ERP

Системный администратор 1С v8.3 (Управляемые формы) 1С:ERP Управление предприятием Управленческий учет Промышленность, строительство и АПК
← На главную

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

Природа возникновения временных файлов в PostgreSQL

Для начала разберемся, почему PostgreSQL вообще создает файлы в каталоге pgsql_tmp. Это происходит в тех случаях, когда СУБД не хватает выделенной оперативной памяти для выполнения операций сортировки, группировки или построения хеш-таблиц при соединениях (JOIN). В настройках PostgreSQL за этот лимит отвечает параметр work_mem.

Рассмотрим ситуацию: если для запроса 1С требуется отсортировать объем данных в 1 ГБ, а параметр work_mem установлен в значение 256 МБ, Postgres будет вынужден сбрасывать промежуточные результаты на диск. В сложных запросах ERP, где количество соединений и вложенных подзапросов исчисляется десятками, таких операций может быть множество, и каждая из них может порождать свой временный файл.

Анализ проблемного запроса в модуле РасчетЗарплатыРасширенный

Как показывает практика и сообщения специалистов, одним из виновников часто становится процедура СоздатьВТНачисленияСотрудниковПоПоказателямПерерасчетов. Проанализируем фрагмент запроса, который может приводить к деградации производительности:


ВЫБРАТЬ РАЗЛИЧНЫЕ
    СотрудникиПериоды.Период КАК Период,
    СотрудникиПериоды.Организация КАК Организация,
    СотрудникиПериоды.Сотрудник КАК Сотрудник,
    СотрудникиПериоды.Начисление КАК Начисление,
    Начисления.ЯвляетсяЛьготой КАК ЯвляетсяЛьготой,
    СотрудникиПериоды.ИзмененныеДанные КАК ИзмененныеДанные
ПОМЕСТИТЬ ВТНачисленияСотрудниковПоПоказателямПерерасчетов
ИЗ ВТИзмеренияДатыДляСрезаПлановыхНачислений КАК СотрудникиПериоды
ВНУТРЕННЕЕ СОЕДИНЕНИЕ ПланВидовРасчета.Начисления КАК Начисления
    ПО СотрудникиПериоды.Начисление = Начисления.Ссылка
ЛЕВОЕ СОЕДИНЕНИЕ Справочник.ПоказателиРасчетаЗарплаты КАК ПоказателиРасчетаЗарплаты
    ПО ПоказателиРасчетаЗарплаты.Ссылка = СотрудникиПериоды.ИзмененныеДанные
ЛЕВОЕ СОЕДИНЕНИЕ ВТПлановыеНачисленияСрезПоследних КАК ПлановыеНачисления
    ПО СотрудникиПериоды.Период = ПлановыеНачисления.Период
    И СотрудникиПериоды.ГоловнаяОрганизация = ПлановыеНачисления.ГоловнаяОрганизация
    И СотрудникиПериоды.Сотрудник = ПлановыеНачисления.Сотрудник
    И СотрудникиПериоды.Начисление = ПлановыеНачисления.Начисление
    И (НЕ ПоказателиРасчетаЗарплаты.ПериодическийПоказательСотрудника
        ИЛИ СотрудникиПериоды.ДокументОснование = ПлановыеНачисления.ДокументОснование)
    И (ПлановыеНачисления.Используется)
ГДЕ (НЕ ПлановыеНачисления.Период ЕСТЬ NULL
    ИЛИ Начисления.СпособВыполненияНачисления = ЗНАЧЕНИЕ(Перечисление.СпособыВыполненияНачислений.ПоЗначениюПоказателяПриОкончательномРасчете))

В данном запросе критическим моментом является использование ВЫБРАТЬ РАЗЛИЧНЫЕ (DISTINCT) в сочетании с множественными левыми соединениями. Если во временных таблицах ВТИзмеренияДатыДляСрезаПлановыхНачислений или ВТПлановыеНачисленияСрезПоследних данные не уникализированы должным образом, возникает эффект «картезианского произведения», когда количество строк в результате начинает расти в геометрической прогрессии. СУБД пытается обработать этот массив данных, не умещается в work_mem и забивает диск временными файлами.

Шаг 1: Оптимизация параметров PostgreSQL

Выясним, какие настройки сервера СУБД помогут локализовать проблему и предотвратить падение всей системы:

  1. Параметр work_mem: Не стоит бездумно увеличивать его до гигантских значений. Помните, что work_mem выделяется на каждую операцию внутри каждого сеанса. Для базы ERP объемом 15-50 ГБ оптимально установить work_mem в диапазоне 128MB - 256MB.
  2. Параметр temp_file_limit: Это критически важная настройка. Установите жесткий лимит на объем временных файлов для одного процесса (например, 20 ГБ). В этом случае проблемная транзакция просто прервется с ошибкой, но не «уронит» весь сервер по нехватке места.
  3. Параметр idle_in_transaction_session_timeout: Часто временные таблицы не удаляются, так как сеанс 1С зависает в статусе "idle in transaction". Установите таймаут (например, 10 минут), чтобы Postgres сам завершал такие сессии.

Шаг 2: Программная оптимизация временных таблиц в 1С

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

Индексация временных таблиц: Обязательно индексируйте временные таблицы по полям, которые участвуют в последующих соединениях. Это позволяет СУБД использовать Index Join вместо тяжелого Hash Join или Nested Loop.


// Пример правильного создания ВТ с индексами
Запрос.Текст = "ВЫБРАТЬ ... ПОМЕСТИТЬ ВТ_Данные ИЗ ... ИНДЕКСИРОВАТЬ ПО Сотрудник, Период";

Удаление ненужных ВТ: Если временная таблица больше не нужна в пакете запроса, ее следует явно удалять. Это освобождает место в pg_temp.


// Явное уничтожение временной таблицы в пакете
Запрос.Текст = "УНИЧТОЖИТЬ ВТ_Данные";

Шаг 3: Обновление платформы и версии СУБД

Проанализируем программное окружение. В тексте обсуждения фигурирует PostgreSQL 10.3 и платформа 8.3.15. Это связка содержит ряд известных проблем:

Проблема пустых дат и типизации

Обратим внимание на конструкцию в логе: T3._APDateFrom <> '0001-01-01 00:00:00'::timestamp. В PostgreSQL работа с "пустыми" датами 1С может вызывать проблемы, если индексы по этим полям не построены корректно. Если запрос содержит сравнение с минимальной датой в условиях соединения, планировщик может ошибочно предположить, что под условие попадает 90% базы, и выбрать заведомо проигрышный план выполнения (Full Scan).

Рекомендация: Проверьте данные в регистрах на наличие аномальных дат. В некоторых случаях перенос условий из ГДЕ непосредственно в секцию ПО соединения помогает планировщику отсечь лишние данные на раннем этапе.

Заключение и выводы

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

  1. Ограничить temp_file_limit в postgresql.conf, чтобы защитить диск от переполнения.
  2. Обновить PostgreSQL до версии 12 или выше.
  3. В процедурах расчета зарплаты ERP проверить наличие индексов у временных таблиц.
  4. Выделить регламентное закрытие месяца в отдельный временной интервал с увеличенными лимитами памяти, если ресурсов сервера недостаточно для параллельной работы пользователей.

Применение этих мер позволит стабилизировать работу 1С:ERP и избежать аварийных ситуаций при закрытии отчетных периодов.

← На главную