Перейти к содержимому
Tez Base

"tempdb is full": ошибка 9002 в 1С - тушим за пять минут и убираем навсегда

· Опубликовано: · Обновлено:

SQL Server SQL Server и PostgreSQL

Рабочий день в разгаре, и у всех, кто сидит в 1С, разом всплывает “Ошибка СУБД”, где упомянуты tempdb и транзакции. Проведение, отчёты, вход новых пользователей остановились одновременно, хотя сервер не перегружен и на дисках рабочей базы место есть. Дальше по порядку: что сломалось, как за пять минут потушить пожар и как сделать, чтобы он не вернулся. Перезагружать сервер наугад не понадобится.

Читаем сообщение об ошибке - в нём весь диагноз

Полный текст выглядит страшно, но пугаться в нём нечего:

Ошибка СУБД:
Microsoft SQL Server Native Client 11.0: The transaction log for database 'tempdb'
is full due to 'ACTIVE_TRANSACTION' and the holdup lsn is (61800:856:252).
HRESULT=80040E14, SQLSrvr: SQLSTATE=42000, state=4, Severity=11, native=9002, line=1

Разбираем по частям - каждая фраза это шаг диагноза:

  • The transaction log for database ‘tempdb’ is full - переполнен журнал транзакций в служебной базе tempdb. Речь именно о её журнале: данные и диск с рабочей базой тут ни при чём.
  • due to ‘ACTIVE_TRANSACTION’ - очистить журнал мешает транзакция, которая до сих пор открыта и удерживает его “хвост”. Пока она не закончилась, записи ей могут понадобиться для отката, и затереть их SQL Server не вправе. Чаще всего эта транзакция рождается не в СУБД, а в коде конфигурации: где именно и как её разбить, разобрано в статье “Длинные транзакции в 1С”.
  • holdup lsn - Log Sequence Number, номер записи в журнале, дальше которой очистка продвинуться не смогла. Проще говоря, адрес виновника.
  • native=9002 - под этим кодом SQL Server сообщает, что журнал переполнен. Номер стоит запомнить: именно по нему удобнее всего искать эту ошибку и настраивать мониторинг.

Если по-простому: транзакцию кто-то открыл и держит, а журнал tempdb тем временем растёт. Когда рост упирается в предел, ошибку получает каждый, кому нужна tempdb, а нужна она почти всем. Ключевое слово - длинная транзакция. Диск и размер журнала здесь следствие, а не причина.

Почему tempdb касается каждой базы 1С

На весь экземпляр SQL Server tempdb одна, это общее рабочее пространство. И 1С нагружает её куда сильнее, чем принято думать, причём разработчик этого часто не замечает:

  • Временные таблицы запросов. Всякий ПОМЕСТИТЬ пакетного запроса создаёт таблицу в tempdb. Отчёт на 15 пакетов без труда наплодит десяток таких таблиц, и все они проживут, пока запрос не закончится.
  • Сортировки и соединения. Если под ORDER BY или крупный JOIN памяти сервера не хватило, промежуточные данные уходят в tempdb (spill to tempdb).
  • Version store - самый неочевидный пункт. Современные конфигурации работают в режиме управляемых блокировок, и под него на базе 1С включают READ COMMITTED SNAPSHOT, чтобы читатели не блокировали писателей. Платой становится version store в tempdb: туда SQL Server складывает версии изменяемых строк. Достаточно одной живой длинной транзакции, и хранилище перестаёт очищаться и растёт. Это прямая обратная сторона борьбы с блокировками: включая RCSI, вы переносите часть нагрузки в tempdb (подробнее про сам RCSI и блокировки - в статье “Блокировки в 1С: почему в пик всё встаёт”).
  • Реструктуризация и обновления. Когда обновление конфигурации перестраивает большую таблицу, временное пространство тоже расходуется гигабайтами.

Отсюда вывод: сообщение о переполненном журнале tempdb почти никогда не говорит о маленьком диске. Оно говорит, что в системе что-то породило длинную транзакцию. Поэтому и лечение начинается не с диска, а с поиска этой транзакции. Если 9002 прилетает не первый раз, искать держателя вручную каждую неделю бессмысленно: это работа по коду и настройкам СУБД, то есть оптимизация производительности 1С.

Первая помощь: пять минут на диагноз

Все команды ниже только читают служебную информацию - они безопасны для боевого сервера. Выполняются в SQL Server Management Studio под правами администратора СУБД.

Шаг 1. Проверить, насколько заполнен журнал и в нём ли дело:

DBCC SQLPERF(LOGSPACE);

Смотрим строку tempdb: если журнал занят на 90 % и больше, вы по адресу.

Шаг 2. Узнать у tempdb, что не даёт очистить журнал:

SELECT name, log_reuse_wait_desc
FROM sys.databases
WHERE name = 'tempdb';

Увидели ACTIVE_TRANSACTION в log_reuse_wait_desc - значит, диагноз из текста ошибки подтвердился.

Шаг 3. Найти в tempdb транзакцию, открытую раньше всех:

DBCC OPENTRAN('tempdb');

Команда вернёт SPID сессии и момент, когда транзакция началась. Часто этого уже хватает: обычная транзакция 1С длится секунды, а этой, скажем, 40 минут.

Шаг 4. Выяснить, чья она - сеанс, фон или чей-нибудь Management Studio:

SELECT s.session_id, s.host_name, s.program_name, s.login_name,
       at.transaction_begin_time,
       r.status, r.command, r.wait_type,
       r.total_elapsed_time / 1000 AS sec
FROM sys.dm_tran_session_transactions t
JOIN sys.dm_tran_active_transactions at ON at.transaction_id = t.transaction_id
JOIN sys.dm_exec_sessions s ON s.session_id = t.session_id
LEFT JOIN sys.dm_exec_requests r ON r.session_id = s.session_id
ORDER BY at.transaction_begin_time;

Самые давние транзакции окажутся сверху. По host_name и program_name понятно, откуда транзакция: сеанс 1С, фоновое задание, клиент разработчика. SPID с сеансом 1С сопоставляется в консоли администрирования кластера: у сеанса есть поле “Соединение с СУБД”, это тот же номер.

Шаг 5. Что делать дальше - три варианта, от самого предпочтительного:

  1. Дождаться завершения, когда процесс законный и вот-вот закончится (скажем, закрытие месяца уже на последней стадии). Бывает, что лучше всего десять минут ничего не трогать.
  2. Штатно завершить сеанс 1С в консоли кластера. После отката транзакции журнал освободится.
  3. Крайняя мера - снять сессию прямо в SQL Server. Учтите: откат длинной транзакции способен идти почти столько же, сколько она жила, и всё это время журнал ей нужен. Мгновенного облегчения KILL не даёт.

Если журналу физически некуда расти (задан предел размера или закончился диск), сначала оживите систему, временно увеличив файл журнала или его лимит, а с виновником разбирайтесь уже после. Прибавки в пару гигабайт хватит. Снимать предел совсем не стоит: журнал без лимита, лежащий на общем диске, рано или поздно съест весь диск.

Кто обычно оказывается виновником

Если собрать наши разборы (базы от десятков гигабайт и до нескольких терабайт), держатели журнала выстраиваются примерно так:

  1. Самописная обработка, где весь объём идёт одной транзакцией. Логика автора понятна: “500 000 строк за одну транзакцию, зато атомарно”. Атомарность будет, работы не будет. Делите на порции: на тысячу документов тысяча коротких транзакций.
  2. Тяжёлый отчёт посреди рабочего дня. В пакете десяток временных таблиц, в каждой миллионы строк. Часами транзакцию такой отчёт не держит, но вместе с очередью проведения делает в tempdb тесно, и первым падает тот, кому повезло меньше всех.
  3. Фоновое задание, “зависшее” в ожидании блокировки. С открытой транзакцией оно стоит в очереди за ресурсом, а журнал всё это время копится. Лечить нужно причину ожидания, журнал тут ни при чём, и это уже территория блокировок и взаимоблокировок.
  4. Регламент СУБД в неудачное окно - например, индексы перестраиваются прямо в рабочие часы.

Профилактика: чтобы 9002 не возвращалась

1. Настройте tempdb - и различайте, что чем лечится

Здесь чаще всего смешивают два разных отказа. Настройки файлов данных tempdb и настройки её журнала лечат разные ошибки, и подменять одно другим бесполезно.

На 9002 влияет ровно один файл - журнал tempdb:

  • Начальный размер журнала подбирайте под реальную нагрузку, 8 МБ по умолчанию для неё не годятся. Когда tempdb после каждой перезагрузки заново набирает объём автоприростами, выставьте стартовый размер таким, каким он обычно бывает в работе.
  • Автоприрост ставьте фиксированный, например 512 МБ: процентный даёт всё более крупные и всё более редкие, но болезненные рывки.
  • Свободное место на томе, куда этому журналу расти. Ноль свободного места - та же 9002, сколько ни настраивай остальное.

Файлы данных - это про другую ошибку. Несколько файлов одинакового размера (для начала столько, сколько ядер, но максимум восемь) и пропорциональное заполнение снимают конкуренцию за служебные страницы (ожидания PAGELATCH) и переполнение самих файлов данных - то есть ошибку 1105. К заполнению журнала они отношения не имеют.

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

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

Настройка tempdb - один из шагов общей настройки сервера под 1С; полный чек-лист “что крутить, прежде чем покупать железо” - в статье “1С тормозит: что делать”.

2. Уберите длинные транзакции в коде 1С

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

3. Наведите порядок во временных таблицах пакетных запросов

Временная таблица из ПОМЕСТИТЬ, которую никто не уничтожил до конца пакета, занимает место в tempdb, пока выполняется весь запрос. В длинном отчётном пакете так зря заняты гигабайты: таблица нужна была только третьему пакету, а место держит до пятнадцатого. Лекарство - привычка ставить УНИЧТОЖИТЬ сразу за последним обращением к таблице. Заодно это часть общей гигиены запросов, которую мы разбирали в приёмах оптимизации запросов 1С.

Но не ждите от этого спасения журнала. УНИЧТОЖИТЬ внутри открытой транзакции не вернёт вам ни байта: усечение всё равно упирается в самую старую активную транзакцию, а сам DROP пишется в журнал - в fn_dblog на нём видно LOP_DELETE_ROWS. Прямой выигрыш дисциплины УНИЧТОЖИТЬ - в файлах данных tempdb, то есть против той же 1105. На 9002 она действует только косвенно: короче пакет - короче транзакция - раньше сдвигается минимальная LSN.

4. Поставьте мониторинг, чтобы узнавать первым, а не от пользователей

  • Алерт при заполнении журнала tempdb выше 70-80 %.
  • Алерт на транзакции, которым больше пяти минут: запрос из шага 4, запущенный по расписанию.
  • Уведомление на каждую 9002 в логе SQL Server, даже если потом “само рассосалось”: следующая может и не рассосаться. Как выстроить такие алерты - в разборе мониторинга 1С на Grafana.

Размеры и автоприрост tempdb, алерты и контроль длинных транзакций - это одна строка общего регламента СУБД. Когда такого регламента нет вовсе, мы собираем его целиком в рамках обслуживания базы 1С: бэкапы, индексы, статистика, журналы и tempdb под ваше ночное окно.

Чек-лист на стену

  1. Видите 9002 по tempdb - ищите длинную транзакцию. Диск тут следствие, а не причина.
  2. DBCC SQLPERF(LOGSPACE) → log_reuse_wait_desc → DBCC OPENTRAN: за пять минут тремя командами находим виновника.
  3. Сеанс снимаем штатно, в консоли кластера. KILL оставляем на крайний случай и помним, что откат тоже требует времени.
  4. Профилактика: короткие транзакции - единственное, что реально лечит 9002. Журнал tempdb (размер, шаг прироста, место на томе) даёт запас времени; файлы данных и УНИЧТОЖИТЬ - это про соседнюю ошибку 1105. Мониторинг с алертами - чтобы узнать первым.

Когда 9002 возвращается снова и снова, и каждый раз с новым виновником, дело уже в характере нагрузки, случайностью это не назовёшь. Смотреть тогда надо всю систему: от настроек СУБД до того, как устроены самые тяжёлые обработки. Мы это делаем в рамках оптимизации производительности 1С: начинаем с бесплатного экспресс-аудита - снимаем реальную картину по монитору СУБД и техжурналу и показываем, что именно держит tempdb и как это убрать без покупки нового сервера.

Готовые обработки по теме

Чтобы не собирать диагностику руками: Диагностика журнала транзакций прямо в момент аварии называет держателя транзакции по имени пользователя и компьютеру и объясняет log_reuse_wait_desc человеческими словами - она нужна тем, у кого доступа к SQL Server нет вовсе. Чек-ап СУБД под 1С за один прогон проверяет настройки SQL Server и tempdb и выдаёт вердикт (на странице демо-отчёт на боевой базе), а Оптимизатор временных таблиц расставляет УНИЧТОЖИТЬ в пакетных запросах и снимает лишнюю нагрузку с tempdb. Если tempdb кончался вчера, а сервер с тех пор перезагружали, ответить “кто” уже нечем: почему так выходит и что записывать заранее, разобрано в статье какие следы аварии остаются после перезагрузки, а саму запись по минутам ведёт Чёрный ящик SQL Server под 1С.

tempdb переполняется снова и снова

Найдём, кто её наливает, и уберём причину: запросы, длинные транзакции, настройки файлов

Стоимость
150 000 - 450 000 ₸ТЗ и оптимизация под ключ, без налогов; доработки сверх плана - единым счётом по факту диагностики
Срок
от 3 дней

Рано писать? Измерьте сами

УНИЧТОЖИТЬ стоит в конце пакета, а надо раньше

Открыть обработку

INFOSTART TECH EVENT 2026: конференция для 1с-специалистов. если собираетесь, регистрируйтесь по нашей ссылке. Регистрация →

Читайте также

Ускорит ли внешняя компонента на C++ ваш код 1С: как посчитать до того, как писать

Медленное место в 1С хочется вынести в компоненту на C++, но выигрыш бывает и в тысячу раз, и отрицательный. Разбираем, из чего складывается время компоненты, сколько стоит граница в изолированном режиме и в процессе 1С, с какого объёма компонента окупается и в каких задачах её лучше не писать. Все числа из замера 31 задачи на платформе 8.3.27 с проверкой одинаковости результата.

Почему нейросеть повторяет одно и то же: карта внимания модели, снятая на встроенном языке 1С

Модель смотрит в вопрос, пока пишет первые три символа ответа, а дальше почти только на себя. Если выключить у неё одну голову внимания из четырёх, верных ответов не остаётся, а больше трети ответов уходят в повтор вроде "стстстст". Разбираем, как снять карту внимания функцией на сорок строк, что она показала на сорока вопросах и что из этого следует для тех, кто работает с большими моделями.

Нейросеть для проверки кода 1С: как проверить её на своём коде до внедрения

Прежде чем отдавать нейросети ревью кода 1С, её стоит принять на своём коде: у нас одна и та же локальная модель нашла 11 дефектов из 13 на учебных процедурах и 0 из 5 на рабочих. Разбираем порядок приёмки: какие два числа считать, из чего собрать проверочный набор, как поднять стенд без интернета и по каким признакам видно, что замер врёт.