Как устранить критический рост tempdb при закрытии месяца в 1С:ERP?

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

Ситуация, когда при расчете себестоимости в тяжелых конфигурациях, таких как 1С:ERP Управление предприятием, временная база данных SQL Server (tempdb) разрастается до невероятных размеров, превышающих объем основной базы в несколько раз, является критической для бизнеса. Мы можем столкнуться с тем, что даже выделение нескольких терабайт дискового пространства не решает проблему — процесс «съедает» всё доступное место и аварийно завершается. Рассмотрим детально, почему это происходит и как найти выход из этой ситуации, опираясь на технические особенности работы 1С и MS SQL Server.

Анализируем причины: почему tempdb переполняется?

Для начала проанализируем, какие механизмы заставляют SQL Server так активно использовать временное хранилище. В 1С:ERP расчет себестоимости — это сложнейший итерационный процесс, включающий решение систем линейных алгебраических уравнений (СЛАУ). Рассмотрим основные технические факторы:

  1. Влияние механизма RCSI (Read Committed Snapshot Isolation). В современных базах 1С часто включен режим READ_COMMITTED_SNAPSHOT. При этом режиме SQL Server хранит версии изменяемых строк в «хранилище версий» (Version Store), которое физически находится в tempdb. Если расчет себестоимости длится 20–30 часов, то всё это время tempdb обязан хранить старые версии всех строк, которые изменяются любыми другими процессами в системе.
  2. Зацикливание при распределении затрат. Если в системе возникают «петли» в цепочках затрат (например, подразделение А оказало услугу подразделению Б, а Б — подразделению А), алгоритм может генерировать гигантские объемы итерационных данных. Количество временных записей при некорректных настройках распределения растет в геометрической прогрессии.
  3. Проблемы со статистикой (Cardinality Estimation). Если статистика по регистрам себестоимости не актуальна, оптимизатор SQL Server может выбрать неверный план запроса. Вместо эффективного соединения таблиц может начаться сброс (spill) данных на диск в tempdb, так как выделенной оперативной памяти не хватает для обработки миллионов строк «в уме».

Шаг 1: Проверка состояния предыдущих периодов

Как показывает практика, «ларчик часто открывается просто». Одной из главных причин аномального поведения системы является некорректное закрытие предыдущего месяца. Даже если формально месяц отмечен как «закрытый», в нем могут остаться логические ошибки, которые система пытается исправить в текущем периоде.

Рассмотрим алгоритм проверки:

  1. Вернемся в предыдущий отчетный месяц и запустим процедуру закрытия заново в режиме проверки.
  2. Особое внимание уделим регистру накопления ПрочиеРасходы. Выясним, нет ли в нем зависших остатков по статьям, которые должны были распределиться «на себестоимость товаров».
  3. Если в прошлом периоде остались отрицательные остатки в суммовом выражении при нулевом количестве (так называемые «хвосты»), система в текущем месяце будет бесконечно пытаться их скорректировать, создавая колоссальную нагрузку на tempdb. В этом случае поможет автоматическое устранение отрицательных остатков.

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

Шаг 2: Техническая диагностика запросов SQL

Чтобы понять, какая именно часть расчета вызывает рост, проанализируем активность SQL Server. Мы можем использовать SQL Базомер или следующий запрос для мониторинга использования tempdb конкретными сессиями:


SELECT
    s.session_id,
    s.login_name,
    s.host_name,
    t5.text AS [Query Text],
    (user_objects_alloc_page_count + internal_objects_alloc_page_count) * 8 / 1024 AS [AllocatedMB],
    (user_objects_dealloc_page_count + internal_objects_dealloc_page_count) * 8 / 1024 AS [DeallocatedMB]
FROM sys.dm_db_session_space_usage AS s
JOIN sys.dm_exec_requests AS r ON s.session_id = r.session_id
CROSS APPLY sys.dm_exec_sql_text(r.sql_handle) AS t5
WHERE s.session_id > 50;

Этот запрос позволит нам увидеть, какой именно SQL-запрос от 1С «пожирает» место. Часто это бывают огромные временные таблицы, создаваемые при детализации себестоимости до дополнительных расходов. Если мы видим, что объем AllocatedMB исчисляется сотнями гигабайт, значит, мы столкнулись либо с логической петлей в данных, либо с декартовым произведением (Cartesian Product) из-за пустых аналитик в регистрах.

Шаг 3: Настройка параллельного расчета

В настройках 1С:ERP существует возможность включить параллельный расчет себестоимости. Проанализируем, как это влияет на ресурсы. При большом количестве потоков каждый поток создает свои собственные копии временных таблиц в tempdb. Если дисковая подсистема не справляется, это приводит к лавинообразному росту очереди и объема временных файлов.

Рекомендация: попробуем временно снизить количество потоков расчета до 1 или 2 в настройках параметров системы. Это позволит локализовать проблему и убедиться, что рост не связан с избыточным параллелизмом.

Шаг 4: Проверка регистра «Партии товаров организаций»

Разберем ситуацию с партионным учетом. При переходе между версиями ERP (например, с 2.2 на 2.5) или смене учетной политики могут остаться некорректные записи в технических регистрах. Если в регистре ПартииТоваровОрганизаций присутствуют записи с пустой аналитикой (например, не указан Склад или Заказ), механизм распределения партий может пытаться сопоставить их со всеми доступными документами поступления. Это создает гигантскую временную таблицу в памяти SQL, которая мгновенно сбрасывается в tempdb.

Для поиска таких записей воспользуемся стандартными консолями запросов или выполним сравнение регистров «Товары на складах» и «Товары организаций», проверяя наличие пустых значений в ключевых измерениях регистров:

Шаг 5: Оптимизация на уровне SQL Server

Если программные методы не помогают, проанализируем настройки самого сервера баз данных. Рассмотрим следующие шаги:

  1. Обновление статистики: перед закрытием месяца выполним полную очистку процедурного кеша и обновление статистики с параметром FULLSCAN для всех таблиц, участвующих в расчете себестоимости (регистры накопления СебестоимостьТоваров, ВыручкаИСебестоимостьПродаж).
  2. Настройка файлов tempdb: убедимся, что tempdb разделен на несколько файлов одинакового размера (согласно количеству ядер процессора, но обычно не более 8). Это поможет избежать конкуренции за страницы (PFS/GAM contention) и немного ускорит работу, хотя и не спасет от роста объема.
  3. Флаги трассировки: в некоторых случаях помогает использование флагов трассировки (например, 1118 или 2371 для старых версий SQL), которые меняют логику выделения страниц и обновления статистики.

Подводим итоги: пошаговый план решения

Выясним краткую последовательность действий, если ваш tempdb начал бесконтрольно расти:

  1. Остановить расчет и проверить статус закрытия предыдущего месяца. Устранить там все ошибки в распределении расходов.
  2. Очистить «битые» записи: проверить регистры на наличие дат из «будущего» или «глубокого прошлого», а также на наличие пустых аналитик в движениях.
  3. Проверить регистр «Прочие расходы»: он должен быть полностью закрыт в части статей, распределяемых на себестоимость.
  4. Обновить статистику в базе данных MS SQL.
  5. Запустить закрытие месяца, предварительно уменьшив количество потоков расчета себестоимости до минимума.

Помните, что SQL версия ERP — это не про экономию места, но рост временной базы до 2.7 ТБ при основном объеме 2 ТБ — это всегда признак логической ошибки в данных или зацикливания алгоритма, а не нормальное поведение системы. Регулярный аудит корректности закрытия прошлых периодов и контроль чистоты данных в регистрах — залог стабильной работы процедуры закрытия месяца.

← На главную