Как уменьшить размер файла tempdb в SQL Server после выполнения «кривого» запроса в 1С

Системный администратор IT и автоматизация бизнеса
← На главную

Работа в среде 1С:Предприятие часто сопряжена с интенсивным использованием временных таблиц. В некоторых случаях неудачно написанный или слишком тяжелый запрос может привести к взрывному росту временной базы данных tempdb. Ситуация осложняется тем, что даже после завершения запроса или перезагрузки сервера SQL файл базы данных (обычно это tempdb.mdf) не спешит возвращаться к исходным размерам, занимая драгоценное место на диске. Для анализа занятого места можно использовать SQL Базомер (8.2, 8.3), а в этой статье мы рассмотрим подробно, почему это происходит и как правильно вернуть контроль над дисковым пространством.

Почему перезагрузка сервера не помогает уменьшить файл

Многие администраторы ожидают, что перезапуск службы SQL Server автоматически очистит и сожмет tempdb. Это верно лишь отчасти: при старте SQL Server действительно пересоздает временную базу с нуля, удаляя все данные. Однако существует важный нюанс — параметр Initial Size (Начальный размер). Для глубокого анализа происходящего в системе пригодится Монитор кластеров серверов, а мы разберем механизм работы этого параметра подробнее.

Если во время сеанса работы размер файла вырос, а затем была предпринята попытка изменить настройки базы через графический интерфейс (SSMS) или команду ALTER DATABASE, SQL Server может зафиксировать текущий (раздутый) размер как «начальный». В результате, сколько бы раз мы ни перезагружали службу, сервер будет резервировать на диске ровно тот объем, который указан в метаданных как стартовый. Чтобы исправить это, нам необходимо явно указать серверу новый целевой размер перед перезагрузкой.

Правильный алгоритм уменьшения размера tempdb

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

  1. Подготовка к сжатию: Перед выполнением команд сжатия рекомендуется выполнить сброс «грязных» страниц из памяти на диск и очистить кэш планов запросов. Это освободит внутренние объекты, которые могут блокировать перемещение страниц внутри файла.
    
    CHECKPOINT;
    GO
    DBCC FREEPROCCACHE;
    GO
    DBCC DROPCLEANBUFFERS;
    GO
    
  2. Изменение конфигурации файла: Вместо простого сжатия, мы сообщим SQL Server, какой размер файла должен быть установлен при следующем запуске. Воспользуемся командой MODIFY FILE. Выясним логическое имя файла (обычно это tempdev для данных и templog для лога).
    
    USE [master];
    GO
    ALTER DATABASE [tempdb] MODIFY FILE (NAME = N'tempdev', SIZE = 2048MB);
    GO
    ALTER DATABASE [tempdb] MODIFY FILE (NAME = N'templog', SIZE = 512MB);
    GO
    
  3. Перезапуск службы: После выполнения этих команд необходимо перезапустить службу SQL Server. После старта файлы примут указанный размер.

Разбор причин, блокирующих сжатие (Shrink)

Посмотрим на ситуацию, когда мы пытаемся выполнить DBCC SHRINKFILE «на лету», но получаем ошибку или отсутствие результата. В среде 1С это часто вызвано следующими факторами:

Активные транзакции и RCSI: 1С:Предприятие практически всегда использует режим Read Committed Snapshot Isolation (изоляция снимка). Это означает, что в tempdb находится «Хранилище версий» (Version Store). Если в базе есть хотя бы одна «зависшая» или очень долгая транзакция, SQL Server не сможет удалить старые версии данных из tempdb, и сжатие будет заблокировано. Проанализируем состояние хранилища версий с помощью запроса:


SELECT SUM(version_store_reserved_page_count) AS [Pages],
(SUM(version_store_reserved_page_count) * 8 / 1024.0) AS [Size_MB]
FROM sys.dm_db_file_space_usage;

Внутренние объекты 1С: Платформа активно создает глобальные и локальные временные таблицы (те самые #tt1, #v8_option и др.). Пока сеанс пользователя 1С не завершен или не вызван метод УдалитьВременныеТаблицы() в коде, эти объекты удерживают место.

Оптимизация: RAM-диск и износ NVMe

В обсуждении часто всплывает вопрос переноса tempdb на RAM-диск (память) или скоростные NVMe-накопители. Рассмотрим плюсы и риски этого подхода.

Использование RAM-диска позволяет радикально ускорить работу с временными таблицами и снизить нагрузку на дисковую подсистему. Однако, как справедливо замечено, при переполнении такого диска работа всей системы остановится с критической ошибкой. Проанализируем гибридный метод решения этой проблемы:

  1. Создаем основной файл tempdb на RAM-диске фиксированного размера (например, 16 ГБ).
  2. Создаем вторичный файл данных (Secondary Data File) на обычном быстром SSD/NVMe с включенным авторасширением.
  3. SQL Server будет распределять нагрузку между файлами, но при исчерпании места на RAM-диске система продолжит работу за счет расширения файла на физическом носителе.

Важное замечание по NVMe: Если вы замечаете быстрый износ (падение SMART до 37% за короткий срок), это верный признак того, что в 1С выполняются крайне неоптимальные запросы. Посмотрим на мониторинг: если USR1CV8 постоянно пишет огромные объемы данных, необходимо использовать Технологический журнал 1С для поиска запросов с огромным количеством записей во временных таблицах.

Что будет, если просто удалить файл вручную?

Ни в коем случае не пытайтесь удалять файлы .mdf или .ldf базы tempdb при остановленной службе SQL, если вы не уверены в корректности путей. Если вы удалите файл и при этом измените конфигурацию дисков (например, RAM-диск не создастся после перезагрузки), служба SQL Server просто не запустится.

Если такая ситуация произошла, нам придется запускать SQL Server в режиме восстановления конфигурации (флаг -f), чтобы через консоль sqlcmd прописать корректные пути к файлам данных.

Выводы

Для эффективного управления размером tempdb мы рекомендуем:

← На главную