Что делать, если MSSQL Server загружает процессор на 100% при работе с 1С: поиск скрытых причин

Системный администратор 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

Каждый системный администратор и разработчик 1С рано или поздно сталкивается с ситуацией, когда сервер СУБД внезапно начинает потреблять 100% ресурсов процессора. Процесс sqlservr.exe утилизирует все доступные мощности, пользователи жалуются на зависание отчетов, а базы данных ЗУП, БП или УТ практически перестают отвечать на запросы. При этом стандартное тестирование и исправление (ТИИ) в 1С, а также проверка базы данных средствами СУБД (DBCC CHECKDB) не показывают абсолютно никаких ошибок.

В этой статье мы подробно разберем нестандартную, но часто встречающуюся причину такого поведения — скрытую деградацию дискового массива, а также проанализируем сопутствующие факторы, такие как обновления операционной системы и неоптимальные настройки параллелизма в MSSQL. Мы научимся выявлять "тяжелые" запросы и правильно конфигурировать сервер для предотвращения подобных сбоев.

Почему умирающий жесткий диск нагружает именно процессор?

На первый взгляд кажется логичным, что при выходе диска из строя или деградации RAID-массива в системном мониторе (Performance Monitor) должна вырасти очередь к диску (Physical Disk Queue Length), а процессор должен бездействовать в ожидании операций ввода-вывода (параметр % inside CPU / page faults). Однако на практике сервер СУБД часто уходит в глухую 100% загрузку CPU. Выясним причину этого парадоксального явления.

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

  1. Механизм спинлоков (Spinlocks) и активное ожидание: SQL Server спроектирован как высокопроизводительная система с собственным планировщиком потоков (SQLOS). Когда поток СУБД запрашивает чтение данных из буферного пула (памяти), а нужной страницы там не оказывается, инициируется физическое чтение с диска. Если диск начинает "сыпаться" или зависать на операциях позиционирования головок, время ожидания ответа резко возрастает. Чтобы избежать дорогостоящей для процессора операции переключения контекста (Context Switch), поток SQL Server не засыпает сразу. Вместо этого он начинает выполнять так называемое "активное ожидание" (spinning), циклически опрашивая процессор в надежде, что ресурс освободится в ближайшие микросекунды. Когда таких запросов сотни, ядра процессора моментально утилизируются под 100% бесполезными циклами опроса.
  2. Прерывания DPC/ISR драйвера контроллера: Сбоящий физический накопитель заставляет дисковый контроллер постоянно повторять попытки чтения поврежденных секторов. Это порождает колоссальное количество аппаратных прерываний (ISR — Interrupt Service Routines) и отложенных вызовов процедур (DPC — Deferred Procedure Calls). Диспетчер задач Windows очень часто суммирует процессорное время, затраченное на обработку этих прерываний драйверов, и визуально относит его к процессу, который инициировал операцию ввода-вывода — то есть к sqlservr.exe.

Скрытое влияние обновлений операционной системы

Часто триггером проблемы выступает обычное обновление Windows Server. Проанализируем ситуацию на примере обновлений, связанных с аппаратными уязвимостями процессоров (такими как Spectre и Meltdown). Данные патчи безопасности изолируют память ядра от пользовательских процессов.

После установки этих обновлений производительность дисковых операций ввода-вывода (I/O) на старых поколениях процессоров (например, Intel Xeon Haswell/Broadwell) может снизиться на 15–40%. Если до установки обновлений процессор сервера имел избыточную мощность и успевал сглаживать задержки дисковой подсистемы, то после наката патчей любая повышенная дисковая активность (например, ресурсоемкий отчет по статусам в самописной конфигурации) моментально выводит загрузку CPU на критический уровень.

Как локализовать проблему: ищем тяжелые запросы

Если сервер СУБД перегружен, нам необходимо определить, какие именно запросы вызывают наибольшую нагрузку на процессор за последний час. Для этого мы можем использовать специальный системный скрипт, анализирующий динамические административные представления (DMV) SQL Server.

Рассмотрим подробнее этот скрипт. Он собирает статистику по времени выполнения запросов, планам их выполнения и сопоставляет их с конкретными базами данных:


-- Шаг 1. Создаем временную таблицу T1 для расчета общего времени работы процессора
SELECT SUM(qs.max_elapsed_time) as elapsed_time, SUM(qs.total_worker_time) as worker_time 
INTO T1 
FROM ( 
    SELECT TOP 100000 * 
    FROM sys.dm_exec_query_stats qs 
    WHERE qs.last_execution_time > (CURRENT_TIMESTAMP - '01:00:00.000') 
    ORDER BY qs.last_execution_time DESC 
) as qs ; 

-- Шаг 2. Выбираем детальную информацию по тяжелым запросам в таблицу T2
SELECT TOP 10000 
    (qs.max_elapsed_time) as elapsed_time, 
    (qs.total_worker_time) as worker_time, 
    qp.query_plan, 
    st.text, 
    dtb.name, 
    qs.*, 
    st.dbid 
INTO T2 
FROM sys.dm_exec_query_stats qs 
CROSS APPLY sys.dm_exec_query_plan(qs.plan_handle) qp 
CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) st 
LEFT OUTER JOIN sys.databases as dtb ON st.dbid = dtb.database_id 
WHERE qs.last_execution_time > (CURRENT_TIMESTAMP - '01:00:00.000') 
ORDER BY qs.last_execution_time DESC ; 

-- Шаг 3. Выводим ТОП-100 самых ресурсоемких запросов с указанием процента нагрузки
SELECT TOP 100 
    (T2.elapsed_time*100/T1.elapsed_time) as percent_elapsed_time, 
    (T2.worker_time*100/T1.worker_time) as percent_worker_time, 
    T2.* 
FROM T2 as T2 
INNER JOIN T1 as T1 ON 1=1 
ORDER BY T2.worker_time DESC ; 

-- Шаг 4. Очищаем временные таблицы
DROP TABLE T2 ; 
DROP TABLE T1 ;

Этот запрос позволяет быстро выявить конкретный отчет или регламентное задание 1С, которое перегружает систему. Если в топе вы видите простейшие запросы к небольшим таблицам (например, к регистру сведений или справочнику статусов), которые выполняются аномально долго — это верный признак проблем с дисковым накопителем или устаревшей статистикой СУБД.

Обязательные настройки MSSQL для баз данных 1С

Чтобы минимизировать риски ухода процессора в 100% из-за одного неоптимального отчета или сбоя оборудования, мы должны правильно настроить параметры СУБД. Разберем по шагам ключевые настройки конфигурации SQL Server:

1. Настройка максимальной степени параллелизма (MAXDOP)

По умолчанию параметр Max Degree of Parallelism в SQL Server равен 0. Это означает, что один сложный запрос может задействовать все доступные ядра процессора. Для предотвращения монополизации ресурсов СУБД под управлением 1С установим следующие правила:

2. Порог стоимости параллелизма (Cost Threshold for Parallelism)

Если значение MAXDOP настроено больше 1, обязательно скорректируйте параметр Cost Threshold for Parallelism. По умолчанию он равен 5 (абстрактная единица стоимости плана запроса). Для систем 1С это значение слишком мало — SQL Server пытается распараллеливать даже простейшие операции. Рекомендуется поднять этот порог как минимум до 50.

3. Настройка схемы электропитания Windows

Часто операционная система Windows Server по умолчанию работает в режиме "Сбалансированный" (Balanced). В этом режиме частота ядер процессора динамически снижается при отсутствии нагрузки. При резком запуске тяжелого отчета СУБД начинает требовать ресурсы, но процессор не успевает мгновенно поднять частоту, что приводит к кратковременному зависанию и скачку загрузки до 100%. Обязательно переключите схему питания сервера в режим "Высокая производительность" (High Performance).

4. Регулярное обслуживание индексов и обновление статистики

Маленькие базы данных (объемом до 1 ГБ) крайне чувствительны к актуальности статистики. Если статистика устарела, оптимизатор SQL Server вместо быстрого поиска по индексу (Index Seek) выберет полное сканирование таблицы (Table Scan), что приведет к миллионам логических чтений в оперативной памяти и перегрузке CPU. Настройте ежедневное регламентное задание обновления статистики для всех баз данных 1С.

← На главную