Каждый системный администратор и разработчик 1С рано или поздно сталкивается с ситуацией, когда сервер СУБД внезапно начинает потреблять 100% ресурсов процессора. Процесс sqlservr.exe утилизирует все доступные мощности, пользователи жалуются на зависание отчетов, а базы данных ЗУП, БП или УТ практически перестают отвечать на запросы. При этом стандартное тестирование и исправление (ТИИ) в 1С, а также проверка базы данных средствами СУБД (DBCC CHECKDB) не показывают абсолютно никаких ошибок.
В этой статье мы подробно разберем нестандартную, но часто встречающуюся причину такого поведения — скрытую деградацию дискового массива, а также проанализируем сопутствующие факторы, такие как обновления операционной системы и неоптимальные настройки параллелизма в MSSQL. Мы научимся выявлять "тяжелые" запросы и правильно конфигурировать сервер для предотвращения подобных сбоев.
На первый взгляд кажется логичным, что при выходе диска из строя или деградации RAID-массива в системном мониторе (Performance Monitor) должна вырасти очередь к диску (Physical Disk Queue Length), а процессор должен бездействовать в ожидании операций ввода-вывода (параметр % inside CPU / page faults). Однако на практике сервер СУБД часто уходит в глухую 100% загрузку CPU. Выясним причину этого парадоксального явления.
Существует два ключевых механизма, которые связывают медленную работу дисков с высокой нагрузкой на процессор:
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С, которое перегружает систему. Если в топе вы видите простейшие запросы к небольшим таблицам (например, к регистру сведений или справочнику статусов), которые выполняются аномально долго — это верный признак проблем с дисковым накопителем или устаревшей статистикой СУБД.
Чтобы минимизировать риски ухода процессора в 100% из-за одного неоптимального отчета или сбоя оборудования, мы должны правильно настроить параметры СУБД. Разберем по шагам ключевые настройки конфигурации SQL Server:
По умолчанию параметр Max Degree of Parallelism в SQL Server равен 0. Это означает, что один сложный запрос может задействовать все доступные ядра процессора. Для предотвращения монополизации ресурсов СУБД под управлением 1С установим следующие правила:
MAXDOP = 1. Это полностью исключит распараллеливание запросов и гарантирует стабильную работу других пользователей при запуске тяжелых отчетов.MAXDOP равным числу физических ядер в одном NUMA-узле (обычно от 2 до 4), но ни в коем случае не оставлять его равным 0.Если значение MAXDOP настроено больше 1, обязательно скорректируйте параметр Cost Threshold for Parallelism. По умолчанию он равен 5 (абстрактная единица стоимости плана запроса). Для систем 1С это значение слишком мало — SQL Server пытается распараллеливать даже простейшие операции. Рекомендуется поднять этот порог как минимум до 50.
Часто операционная система Windows Server по умолчанию работает в режиме "Сбалансированный" (Balanced). В этом режиме частота ядер процессора динамически снижается при отсутствии нагрузки. При резком запуске тяжелого отчета СУБД начинает требовать ресурсы, но процессор не успевает мгновенно поднять частоту, что приводит к кратковременному зависанию и скачку загрузки до 100%. Обязательно переключите схему питания сервера в режим "Высокая производительность" (High Performance).
Маленькие базы данных (объемом до 1 ГБ) крайне чувствительны к актуальности статистики. Если статистика устарела, оптимизатор SQL Server вместо быстрого поиска по индексу (Index Seek) выберет полное сканирование таблицы (Table Scan), что приведет к миллионам логических чтений в оперативной памяти и перегрузке CPU. Настройте ежедневное регламентное задание обновления статистики для всех баз данных 1С.