Мазмұнға өту
Tez Base

1С висела, серверы перезагрузили: какие следы аварии остались и сколько они живут

· Жарияланды:

Мониторинг и журналы

Самый частый ответ на вопрос “почему вчера всё висело” звучит как “перезагрузили, и отпустило”. Он честный, но причину не называет. Хуже того, перезагрузка и есть главный стиратель улик: SQL Server после рестарта забывает статистику ожиданий и занятость tempdb, кластер 1С забывает сеансы, журналы с перезаписью дописывают поверх старого.

Ниже разбор по источникам: что каждый из них знает об аварии, сколько это хранится и что надо сделать заранее. Иллюстрацией идёт настоящий случай из розницы, в котором через три недели после зависания касс назвать виновника было уже не по чему. Короткий рассказ о нём опубликован на Инфостарте, здесь методика целиком.

Две минуты до перезагрузки

Если всё висит прямо сейчас и рестарт уже решён, сначала сохраните в файл три вещи. Это занимает пару минут и потом стоит дороже всего остального.

  1. Кто занимает tempdb и кто кого блокирует. Запрос ниже считает и идущие задачи, и сеансы, которые держат временные таблицы между запросами: в 1С это частый случай, ПОМЕСТИТЬ живёт до конца сеанса.
  2. Список сеансов и процессов кластера через rac session list и rac process list.
  3. Текущий ERRORLOG: EXEC xp_readerrorlog 0, 1; с выводом в файл.
-- Кто занимает tempdb: завершённые аллокации сеанса плюс идущие задачи
SELECT TOP (20)
    s.session_id,
    s.host_name,
    s.host_process_id                       AS pid_rphost,
    DB_NAME(s.database_id)                  AS база,
    s.program_name,
    (ss.pages + ISNULL(ts.pages, 0)) * 8 / 1024 AS tempdb_mb,
    r.status,
    r.wait_type,
    r.blocking_session_id,
    at.transaction_begin_time
FROM sys.dm_exec_sessions AS s
JOIN (SELECT session_id,
             SUM(user_objects_alloc_page_count - user_objects_dealloc_page_count
               + internal_objects_alloc_page_count - internal_objects_dealloc_page_count) AS pages
      FROM sys.dm_db_session_space_usage
      GROUP BY session_id) AS ss ON ss.session_id = s.session_id
LEFT JOIN (SELECT session_id,
             SUM(user_objects_alloc_page_count - user_objects_dealloc_page_count
               + internal_objects_alloc_page_count - internal_objects_dealloc_page_count) AS pages
      FROM sys.dm_db_task_space_usage
      GROUP BY session_id) AS ts ON ts.session_id = s.session_id
LEFT JOIN sys.dm_exec_requests AS r ON r.session_id = s.session_id
LEFT JOIN sys.dm_tran_session_transactions AS st ON st.session_id = s.session_id
LEFT JOIN sys.dm_tran_active_transactions AS at ON at.transaction_id = st.transaction_id
WHERE s.is_user_process = 1
ORDER BY tempdb_mb DESC;
rac cluster list localhost:1545
rac session list --cluster=<id кластера> localhost:1545 > sessions.txt
rac process list --cluster=<id кластера> localhost:1545 > processes.txt

Поле host_process_id у соединения 1С совпадает с PID рабочего процесса rphost, а в выводе rac session list у каждого сеанса есть поле db-proc-info с номером соединения СУБД, которое он держит прямо сейчас. Вместе эти три файла отвечают на вопрос “кто” с точностью до сеанса. Через пять минут после рестарта на него не ответит уже никто.

Сколько живёт каждый след

Таблица собрана по реальной описи логов, которую админы сделали через три недели после аварии. Сроки в ней - настройки по умолчанию или то, что стояло на серверах.

ИсточникЧто знает об аварииСколько живётЧто поменять заранее
Статистика SQL Server в памяти (ожидания, задержки файлов, tempdb по сеансам)на чём стоял сервер и кто грузил tempdbдо перезапуска службыписать снимки в свою базу по расписанию
system_healthдолгие ожидания, взаимоблокировки, нехватка памятинесколько файлов по кругу, при активном сервере дниувеличить число и размер файлов или писать свою сессию Extended Events
ERRORLOGперезапуски, kill соединений, часть ошибок6 файлов, новый на каждый старт службы30 файлов
Технологический журнал 1Сдолгие запросы, исключения, ожидания блокировоксколько указано в history, у нас было 48 часов7 суток, плюс TLOCK, TTIMEOUT, TDEADLOCK, EXCP
Сеансы и процессы кластера 1Скто на каком процессе и что держалтолько текущее состояниеписать историю сеансов регламентным заданием
Журнал Application сервера 1Спадения процессов, ошибки служб20 МБ с перезаписью512 МБ
Журнал Systemкто и с какой причиной перезагружалдолго, событие 1074ничего
PerfMonнагрузка по минутамне собирался вовсесборщик счётчиков с записью в файл
Графики vCenterпроцессор, память, диски машинпрошлый месяц только средние за 2 часаничего, минутные пики там не живут
События vCenterрасширения дисков, вход админов в консоль, тревоги хранилищ30 дней по умолчаниюправа на чтение событий хостов заранее

Отдельная оговорка про ERRORLOG. Это единственное место SQL Server, которое помнит что-то после перезапуска, но и он не всё. Часть ошибок нехватки места в tempdb туда не попадает, поэтому пустой ERRORLOG не доказывает, что tempdb был в порядке. Число файлов меняется в свойствах журналов сервера или запросом:

-- Хранить 30 файлов ERRORLOG вместо 6
EXEC xp_instance_regwrite
     N'HKEY_LOCAL_MACHINE',
     N'Software\Microsoft\MSSQLServer\MSSQLServer',
     N'NumErrorLogs',
     REG_DWORD,
     30;

Как доказать, что беда общая для всех баз

Первый вопрос любого разбора: виноват код одной базы или общий слой (СУБД, tempdb, кластер, железо). На него отвечает журнал регистрации, если искать не ошибки, а входы. Кассир при зависании перезапускает 1С, и каждый перезапуск это событие _$Session$_.Start. Фоновые задания и веб-сервисы тоже дают входы, но в обычный день их фон стабилен, поэтому сравнивать надо с тем же днём недели неделей раньше.

// Входы по часам за выбранный день. Запускать на сервере с правами администратора,
// потом тот же код для дня неделей раньше.
Функция ВходыПоЧасам(День) Экспорт

	Отбор = Новый Структура;
	Отбор.Вставить("ДатаНачала", НачалоДня(День));
	Отбор.Вставить("ДатаОкончания", КонецДня(День));
	Отбор.Вставить("Событие", "_$Session$_.Start");

	Записи = Новый ТаблицаЗначений;
	ВыгрузитьЖурналРегистрации(Записи, Отбор, "Дата");

	Результат = Новый Соответствие;
	Для Каждого Запись Из Записи Цикл
		Ч = Час(Запись.Дата);
		Было = Результат[Ч];
		Результат.Вставить(Ч, ?(Было = Неопределено, 0, Было) + 1);
	КонецЦикла;

	Возврат Результат;

КонецФункции

В нашем случае входов в часы аварии было в 7-15 раз больше обычного: 158 против 22 в 14:00, 194 против 16 в 15:00, 233 против 16 в 17:00. Но доказательством стали не числа, а минуты. Пики пришлись на 14:20, 15:10 и 17:10-17:20, и совпали во всех одиннадцати базах сразу. Ошибка в коде одной базы соседей в ту же минуту не роняет, если не забивает общий ресурс. Значит, болел общий слой, а одна база могла быть его причиной.

Метод дорогой. На больших базах выборка журнала регистрации за двое суток падает по таймауту, и позже заказчик запретил её на рабочих базах. Если журнал огромный, берите один час вокруг пика, а не сутки.

Тем же приёмом исключаются блокировки: таймаутов блокировок в рознице в день аварии было 28, неделей раньше тоже 28. Это фон закрытия смен, а не причина.

События vCenter: что видно без доступа к хостам

Если 1С работает под VMware, у админов в истории vCenter лежат вещи, которые сами они не считают уликами. В нашем случае главная находка пришла именно оттуда: в день аварии диск tempdb расширяли трижды, с 250 до 300 ГБ за 1 час 41 минуту. В переписке это выглядело рабочими действиями, а не симптомом.

События читаются без библиотек, голым SOAP на адрес /sdk. REST-интерфейс /api событий не отдаёт. Порядок такой: RetrieveServiceContent, затем SessionManager.Login, дальше запросы с cookie из ответа на вход.

<QueryEvents xmlns="urn:vim25">
  <_this type="EventManager">EventManager</_this>
  <filter>
    <entity>
      <entity type="VirtualMachine">vm-NN</entity>
      <recursion>self</recursion>
    </entity>
    <time>
      <beginTime>2026-01-01T00:00:00Z</beginTime>
      <endTime>2026-01-02T00:00:00Z</endTime>
    </time>
  </filter>
</QueryEvents>

Что искать в ответе:

СобытиеЧто значит
VmReconfiguredEvent с capacityInKB до и последиск расширяли, видно на сколько и когда
VmAcquiredTicketEventадмин открыл консоль машины, то есть кто-то уже смотрел
перезагрузки и выключениясверить с событием 1074 в журнале System

Время в событиях UTC. Графики берутся через QueryPerf, и для прошлого месяца там есть только intervalId 7200, средние за два часа. В них сервер СУБД выглядел спокойным (процессор 13-18 %, задержка дисков до 1 мс), но минутный пик в таком среднем тонет. Снятым подозрение с ресурсов считать нельзя, только ослабленным.

Хронология, которая сложилась, когда события vCenter положили рядом с остальным:

ВремяЧто произошло
около 13:00зависают кассы
13:53диск tempdb 250 → 252 ГБ
14:20первая волна перезапусков 1С во всех базах
14:42диск tempdb 252 → 260 ГБ
15:10падает рабочий процесс rphost, в ту же минуту самая сильная волна
15:34диск tempdb 260 → 300 ГБ
17:22 / 17:25перезагрузка сервера 1С, затем сервера СУБД
20:48ручной рестарт службы SQL Server
21:00ещё одна перезагрузка сервера 1С
утроперезагрузка обоих серверов

Трижды за два часа диск просто так не растят, tempdb явно кончался. Но кто его занял, к этому моменту не знал никто: три запуска SQL Server за сутки трижды обнулили статистику.

Что проверить в настройках, пока ищете виновника

Виновника назвать не удалось, но гипотеза осталась, и её половины проверяются на любом сервере. Первая - параллелизм. На том сервере стояли max degree of parallelism = 0 и cost threshold for parallelism = 5: один запрос мог занять все 48 ядер, а параллельный план получал почти любой запрос. Наутро после аварии за 8 минут прошло 550 взаимоблокировок внутри параллельных запросов.

-- Текущие настройки параллелизма
SELECT name, value_in_use
FROM sys.configurations
WHERE name IN (N'max degree of parallelism', N'cost threshold for parallelism');

-- Значения, которые мы предложили для этого сервера
EXEC sp_configure 'show advanced options', 1; RECONFIGURE;
EXEC sp_configure 'max degree of parallelism', 8; RECONFIGURE;
EXEC sp_configure 'cost threshold for parallelism', 50; RECONFIGURE;

Вторая - брошенная транзакция. В той же инфраструктуре раньше уже был случай: транзакция ERP держала около 56 000 эксклюзивных блокировок и 27 тысяч страниц tempdb, сброс сеанса 1С её не закрыл, помог только KILL на стороне SQL Server. Объём там был около 210 МБ, но механизм тот же: транзакция пережила сеанс, и 1С о ней больше ничего не знала.

-- Транзакции дольше 5 минут: кто держит и сколько журнала
SELECT s.session_id,
       s.host_process_id AS pid_rphost,
       DB_NAME(dt.database_id) AS база,
       at.transaction_begin_time,
       DATEDIFF(MINUTE, at.transaction_begin_time, SYSDATETIME()) AS минут,
       dt.database_transaction_log_bytes_used / 1048576 AS журнал_мб
FROM sys.dm_tran_active_transactions AS at
JOIN sys.dm_tran_session_transactions AS st ON st.transaction_id = at.transaction_id
JOIN sys.dm_exec_sessions AS s ON s.session_id = st.session_id
JOIN sys.dm_tran_database_transactions AS dt ON dt.transaction_id = at.transaction_id
WHERE at.transaction_begin_time < DATEADD(MINUTE, -5, SYSDATETIME())
ORDER BY at.transaction_begin_time;

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

Что поставить заранее

Вывод из этой истории один: следы надо писать до перезагрузки и туда, где рестарт их не достанет.

  • Снимки SQL Server раз в минуту в свою базу. Активные запросы с текстом, tempdb по сеансам, блокировки, долгие транзакции, прирост ожиданий и задержек файлов, место на дисках, хранение две недели. Задание SQL Agent работает внутри сервера СУБД и пишет, даже когда кластер 1С не отвечает. Мы собрали это в Чёрный ящик SQL Server под 1С: на нашем стенде снимок занимает 166 мс, около 0,02 % сервера на 12 ядрах.
  • Связка с сеансами 1С. SQL Server знает у соединения только PID rphost, а на одном процессе живут сеансы разных баз. Точного пользователя даёт свойство сеанса СоединениеСУБД, которое кластер отдаёт через RAS, если его записывать раз в минуту вместе с PID. В ящике это отдельная команда. Историю нагрузки самого кластера копит Анализ нагрузки кластера 1С.
  • Сроки хранения журналов. Техжурнал 7 суток с событиями блокировок и исключений, ERRORLOG 30 файлов, Application 512 МБ.
  • Тревога на свободное место в tempdb. Узнать раньше касс.
  • Ограничения памяти рабочих процессов на кластере. На том сервере их не было, утром процессы держали 73 ГБ, самые большие по 10 ГБ.
  • Порядок действий на аварию, записанный заранее. Первым пунктом: убедиться, что свежий снимок есть, и только потом перезагружать. Когда кассы стоят, все торопятся, и правило, которое не записано и не закреплено за человеком, не выполнится.

В том случае всё это было предложено техлиду заказчика, и на начало ноября внедрение не начиналось. Если нужна такая запись у вас, ставим её под ключ в рамках мониторинга 1С: снимки, сроки журналов и порядок действий на аварию.

1С висела, серверы перезагрузили, а почему висело, сказать нечем

Поставим запись следов до аварии: снимки SQL Server, история кластера, сроки хранения журналов и порядок действий перед рестартом

Құны
450 000 ₸-дентолық ендіру; салықтарсыз
Мерзімі
от 1 дня

Жазуға ерте ме? Өзіңіз өлшеп көріңіз

Чёрный ящик SQL Server под 1С: кто занимал tempdb и держал блокировку, когда всё висело

Өңдеуді ашу

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

Мұны да оқыңыз

Prometheus не принимает метрики кластера 1С: диагностика по симптомам

Справочник по поломкам экспортера метрик кластера 1С: цель down с ошибкой invalid metric type, отказ RAS из-за разных версий, служба RAS, которая перестала стартовать после обновления платформы, пустые панели лицензий на тестовом кластере и ловушки разбора вывода rac. Для каждой поломки команда проверки и починка, в конце список проверок до выпуска.

Ночная загрузка данных упала без видимой ошибки: как узнать об этом в первую же ночь

Одно значение не влезло в числовую колонку, и вся ночная пачка откатилась. Отчёты открываются, цифры вчерашние, алерта нет. Разбираем по вопросам: откуда ноль строк, как найти брак, чем платите за обрезку и расширение типа, какой счётчик ловит аварию сразу и как найти узкие числовые реквизиты в своей 1С.

Сервер 1С грузит процессор: как найти причину и не обвинить не тот процесс

Порядок поиска причины, когда сервер 1С грузит процессор, а в диспетчере задач сверху rmngr или rphost. Проверки расставлены по цене: от накопленного времени ЦП и часового ряда по журналу регистрации до технологического журнала и поиска сервиса внутри менеджера кластера без перезапуска агента. С готовыми скриптами PowerShell и рабочим фильтром техжурнала.