Рост системной базы данных tempdb — одна из самых распространенных проблем при эксплуатации высоконагруженных систем на базе «1С:Предприятие 8.3» и MS SQL Server. Ситуация, когда файл базы данных разрастается до десятков и сотен гигабайт, может привести к полной остановке работы из-за нехватки места на диске. Рассмотрим подробно, почему это происходит, как выявить «виновника» и какие настройки СУБД помогут стабилизировать систему.
Прежде чем приступать к диагностике, разберем механизмы, которые заставляют SQL Server активно использовать временное хранилище. В контексте 1С мы можем выделить три ключевых фактора:
#tt). Если запрос написан неоптимально или программист забыл явно уничтожить временную таблицу в менеджере временных таблиц, она будет занимать место до завершения сеанса или транзакции.GROUP BY, UNION, DISTINCT, а также при операциях сортировки, которые не помещаются в оперативную память, SQL Server создает промежуточные рабочие таблицы в tempdb.Read Committed Snapshot Isolation (RCSI) или Snapshot Isolation, SQL Server хранит версии измененных строк в tempdb. Это критически важный момент для 1С.Важная деталь: Если в системе есть хотя бы одна «зависшая» транзакция, которая началась давно и не завершается, SQL Server не сможет очистить хранилище версий строк. Это приведет к бесконечному росту tempdb, даже если другие пользователи работают корректно.
Выясним причину роста, используя комплексный подход: мониторинг со стороны СУБД и со стороны платформы 1С.
Шаг 1. Анализ активных транзакций в SQL Server
Проанализируем текущую ситуацию в базе с помощью системных динамических представлений. Нам нужно понять, кто именно удерживает место. Рассмотрим использование следующего скрипта для поиска транзакций, наиболее активно использующих tempdb:
SELECT
s.session_id,
s.login_name,
s.host_name,
st.text AS QueryText,
(user_objects_alloc_page_count + internal_objects_alloc_page_count) * 8 / 1024 AS Total_MB,
r.cpu_time,
r.total_elapsed_time
FROM sys.dm_db_session_space_usage AS su
JOIN sys.dm_exec_sessions AS s ON s.session_id = su.session_id
LEFT JOIN sys.dm_exec_requests AS r ON r.session_id = s.session_id
OUTER APPLY sys.dm_exec_sql_text(r.sql_handle) AS st
WHERE (user_objects_alloc_page_count + internal_objects_alloc_page_count) > 0
ORDER BY Total_MB DESC;
Этот запрос покажет нам session_id и текст запроса, который потребляет больше всего страниц в tempdb. Если мы видим огромные значения в колонке Total_MB, значит, мы нашли конкретный запрос или сессию-виновника.
Шаг 2. Настройка технологического журнала 1С
Чтобы сопоставить данные SQL Server с конкретным действием пользователя в 1С (например, открытием отчета или проведением документа), настроим Технологический журнал (ТЖ). Нам необходимо отловить длительные запросы (событие DBMSSQL). Создадим файл logcfg.xml со следующим содержанием:
<config xmlns="http://v8.1c.ru/v8/tech-log">
<log location="C:\LOGS\SQL_QUERIES" history="24">
<event>
<eq property="Name" value="DBMSSQL"/>
<gt property="Duration" value="1000000"/>
</event>
<property name="all"/>
</log>
</config>
В данном примере мы фиксируем все запросы к СУБД длительностью более 10 секунд (длительность в ТЖ указывается в микросекундах). Это позволит нам проанализировать контекст исполнения на стороне 1С. Для автоматизации сбора логов и поиска проблемных запросов можно воспользоваться инструментом для сбора и анализа логов технологического журнала.
Разберем специфические настройки версии 2016, которые напрямую влияют на стабильность tempdb. В этой версии многие параметры, которые раньше требовали ручной настройки (флаги трассировки 1117 и 1118), теперь работают по умолчанию.
Разделение на несколько файлов данных
Для уменьшения конкуренции за страницы метаданных (проблемы GAM/SGAM) рекомендуется разделять tempdb на несколько файлов данных одинакового размера. Общая рекомендация для SQL 2016: количество файлов должно быть равно числу логических ядер процессора, но не более 8. Если файлов будет больше, это может не дать прироста производительности, а при разном размере файлов SQL Server будет использовать их неравномерно.
Мгновенная инициализация файлов (IFI)
Проанализируем настройку Instant File Initialization. Когда tempdb требуется расшириться, SQL Server по умолчанию заполняет новое пространство нулями. На больших объемах это вызывает длительные задержки. Чтобы этого избежать, убедитесь, что учетной записи, под которой запущена служба SQL Server, назначено право "Perform volume maintenance tasks" (Выполнение задач по обслуживанию томов) в локальных политиках безопасности Windows. Это позволит файлам tempdb расти мгновенно. Для комплексного аудита этих и других параметров можно использовать инструмент для автоматической проверки настроек SQL Server.
Рассмотрим по шагам, что делать, если база уже выросла, и как не допустить этого в будущем.
1. Ограничение максимального размера
Установка лимита (Autogrowth -> Maximum Size) — это правильный шаг, чтобы не "положить" весь сервер. Однако, как правильно заметили коллеги, это не решает причину. Когда место закончится, пользователи получат ошибку Could not allocate space for object in database 'tempdb'. Это сигнал к тому, что нужно не просто увеличивать диск, а оптимизировать код 1С.
2. Регулярный перезапуск служб или Shrink?
Перезапуск службы SQL Server полностью пересоздает tempdb с начальными размерами. Это радикальный, но эффективный метод очистки "мусора". Если перезапуск невозможен, можно выполнить процедуру сжатия (shrink), но делать это нужно крайне осторожно:
USE [tempdb]
GO
DBCC FREEPROCCACHE -- Очистка кеша планов (иногда помогает освободить зависимости)
GO
DBCC SHRINKDATABASE(N'tempdb')
GO
Важно: Не используйте AUTO_SHRINK. Это приведет к катастрофическому падению производительности из-за постоянной фрагментации диска.
3. Проверка сетевых подключений
Выясним еще одну неочевидную причину: сетевые сбои. Если клиент разорвал соединение некорректно (завис ПК, моргнул свет), SQL Server может считать транзакцию активной еще в течение долгого времени (по умолчанию до 2 часов). Попробуйте ограничить время ожидания, установив параметр remote query timeout:
EXEC sys.sp_configure N'remote query timeout (s)', N'60'
GO
RECONFIGURE WITH OVERRIDE
GO
Подведем итог: рост tempdb — это не болезнь, а симптом. Чтобы вылечить систему, мы должны:
sys.dm_tran_active_snapshot_database_transactions.Только комплексный мониторинг и своевременная оптимизация кода позволят забыть о проблемах с переполнением дискового пространства.