При администрировании высоконагруженных систем 1С:Предприятие на базе MS SQL Server администраторы часто сталкиваются с ситуацией, когда база данных tempdb начинает вести себя аномально. Она может резко увеличиваться в размерах, занимая все дисковое пространство, или создавать огромную нагрузку на дисковую подсистему (IO), что приводит к "тормозам" во всей системе. Особенно сложно диагностировать такие проблемы, когда они возникают периодически (например, раз в день) и исчезают до того, как удается поймать "виновника".
В этой статье мы подробно разберем методику поиска причин такой нагрузки, проанализируем поведение SQL Server и рассмотрим инструменты, которые помогут выявить проблемные запросы или настройки.
Прежде чем искать "вредителя", давайте разберемся, чем именно может быть занят tempdb. В контексте 1С нагрузку можно разделить на три основные категории:
#tt...). Они используются при проведении документов, в сложных отчетах и запросах. Если Технологический журнал (ТЖ) не показывает сверхтяжелых запросов, возможно, проблема не здесь.READ_COMMITTED_SNAPSHOT (RCSI), копии изменяемых данных хранятся в tempdb.Рассмотрим сценарии диагностики для каждой из этих причин.
Одной из самых частых причин резких всплесков нагрузки на tempdb, которые трудно отловить обычными средствами 1С (консоль, ТЖ), является устаревшая статистика SQL Server.
Суть проблемы: Когда SQL Server строит план выполнения запроса, он опирается на статистику. Если статистика говорит, что запрос вернет 100 строк, сервер выделяет под эту операцию, например, 1 МБ памяти. Но если статистика устарела и по факту возвращается 1 000 000 строк, выделенной памяти не хватает.
В этот момент происходит событие, называемое Spill to TempDB (сброс в tempdb). Сервер вынужден сбрасывать промежуточные данные (сортировки, хэш-таблицы) на диск в tempdb. Это порождает:
tempdb.Как диагностировать: Поскольку в старых версиях SQL Server (например, 2008/2012) нет Query Store, нам поможет SQL Server Profiler. Настроим трассировку, включив следующие события из раздела Errors and Warnings:
Sort Warnings — предупреждения о сбросе сортировки на диск.Hash Warnings — предупреждения о нехватке памяти для хэш-операций.Exchange Spill Event — сброс данных при параллелизме.Если во время "тормозов" вы видите эти события, значит, причина не в сложности кода 1С, а в том, что SQL Server ошибается с оценкой необходимой памяти. Решением может стать обновление статистики:
UPDATE STATISTICS _AccRg12345 WITH FULLSCAN; -- Пример для конкретной таблицы
-- Или обслуживание всей базы
EXEC sp_updatestats;
Вторая распространенная причина — действия пользователей в списках документов или журналах. Даже в обычных формах (ОФ) и тем более в управляемых (УФ), пользователи имеют возможность настраивать отборы.
Механизм возникновения проблемы:
Пользователь открывает журнал документов (например, "Реализация товаров и услуг") и устанавливает отбор по реквизиту составного типа или через точку (разыменовывая поля). Например: Контрагент.ОсновнойМенеджер.ФизЛицо ПОДОБНО "%Иванов%".
Особенно опасны отборы в сочетании с RLS (Row Level Security — ограничение прав доступа на уровне записей). В этом случае платформа 1С генерирует SQL-запрос, который содержит:
JOIN) с таблицами ссылочных типов.Даже если запрос выбирает TOP 20 строк для отображения на экране, для выполнения условий фильтрации и RLS серверу может потребоваться просканировать миллионы записей, создать временные хэш-таблицы в tempdb и только потом выдать результат. В консоли 1С такой запрос может не выглядеть как "зависший", так как он может выполняться порциями, но нагрузку на диск он создает постоянную.
Решение:
Анализировать планы запросов, попадающих в топы по CPU и IO. Обращать внимание на запросы к таблицам _DocumentJournal (Журналы документов) или основным документам с большим количеством JOIN.
Если в базе используется режим изоляции снимков (RCSI), который является стандартом де-факто для 1С, причиной роста tempdb могут быть незакрытые транзакции.
Как это работает:
1. Пользователь запускает отчет или обработку, которая открывает транзакцию.
2. Происходит ошибка, или окно с вопросом, или сеанс "зависает", но транзакция остается открытой (статус SLEEPING, но open_transaction_count > 0).
3. SQL Server не может удалить старые версии строк из tempdb (Version Store), так как они теоретически могут понадобиться этой старой транзакции.
4. Все изменения данных, которые делают другие пользователи, начинают копиться в tempdb. Файл растет бесконтрольно.
Диагностика: Используйте команду для поиска старейшей активной транзакции:
DBCC OPENTRAN;
Также полезно проверить сессии, которые потребляют больше всего места в tempdb. Для этого можно использовать следующий запрос к системным представлениям (работает на версиях SQL 2005+):
SELECT
t.session_id,
t.request_id,
exec_context_id,
ot.task_state,
r.command,
-- Потребление места пользовательскими объектами (в страницах)
t.user_objects_alloc_page_count,
t.user_objects_dealloc_page_count,
-- Потребление места внутренними объектами (сортировки, хэши)
t.internal_objects_alloc_page_count,
t.internal_objects_dealloc_page_count,
es.login_name,
es.program_name,
st.text AS QueryText
FROM sys.dm_db_task_space_usage t
JOIN sys.dm_os_tasks ot ON t.session_id = ot.session_id AND t.request_id = ot.request_id
JOIN sys.dm_exec_sessions es ON t.session_id = es.session_id
LEFT JOIN sys.dm_exec_requests r ON t.session_id = r.session_id
OUTER APPLY sys.dm_exec_sql_text(r.sql_handle) st
WHERE t.session_id > 50
ORDER BY (t.internal_objects_alloc_page_count + t.user_objects_alloc_page_count) DESC;
Этот скрипт покажет, какая именно сессия "накачивает" tempdb прямо сейчас. Обратите внимание на колонку internal_objects_alloc_page_count. Если она велика — это подтверждает гипотезу о проблемах с планом запроса (сортировки/хэши). Для визуализации этих данных и интерактивного анализа текущей нагрузки можно использовать обработку для мониторинга и анализа работы SQL Server.
Чтобы минимизировать влияние таких проблем, проверим настройки самого SQL Server, которые считаются "золотым стандартом" для работы с 1С:
tempdb на несколько файлов данных (обычно рекомендуют количество файлов, равное количеству ядер процессора, но не более 8). Это снижает конкуренцию за страницы распределения (GAM/SGAM contention).tempdb должны быть одного размера и иметь одинаковые параметры автоувеличения. Это важно для того, чтобы алгоритм Proportional Fill равномерно распределял нагрузку.tempdb сразу большой размер (например, чтобы суммарно они занимали 20-30 Гб или больше, в зависимости от обычной пиковой нагрузки). Это предотвратит постоянные операции расширения файлов в рабочее время.Если вы снова столкнетесь с аномальной нагрузкой, действуйте по следующему алгоритму:
tempdb (приведен выше), чтобы найти конкретную сессию.DBCC OPENTRAN на наличие зависших старых транзакций.