Возможно со стороны участников club-a будут дополнения, это только приветствуется.
Высокая загрузка CPU на SQL-сервере.
Для начала определимся, что каждый из нас подразумевает под высокой нагрузкой.
Варианта тут может быть два:
В общем случае значения этих вариантов могут совпадать, но иногда бывают частности, о которых будет упомянуто ниже (Частность 2).
Поэтому на шаге 1 в Диспетчере задач убеждаемся, что ресурсы сервера потребляет именно процесс sqlservr.exe:
Если Диспетчер задач показывает значительную загрузку процесса sqlservr.exe, переходим к следующему шагу.
Если это не так, то ваш анализ практически завершен и достаточно выяснить почему другие процессы потребляют значительные ресурсы CPU, при необходимости завершив их.
Стоит отметить, если на сервере с SQL установлены такие службы DIRECTUM-a как WorkFlow, то для уменьшения нагрузки на CPU имеет смысл перенести их на другой сервер, т.к. в отдельные моменты служба WorkFlow может оказывать значительное влияние на весь сервер в целом (естественно это утверждение актуально в случае большого числа процессов, указанных в файле настроек SBWorkflowSrvSettings.xml).
В некоторых случаях в Activity Monitor фиксируется постоянная 100% загрузка ресурсов процессора SQL-сервера, при этом в диспетчере задач загрузка CPU составляет значительно меньше (например, 50 и менее процентов) и используется только часть ядер.
Основными причинами м.б.:
1. Отключена автоматическая установка соответствия использующихся ядер/потоков SQL-серверу, т.н. Affinity Mask. Ядра/потоки процессора заданы вручную. Для автоматического задания необходимо включить следующую настройку:
2. Используется неверный/ограниченный тип лицензирования по ядрам, тем самым используется только часть ядер, либо часть ядер по какой-либо причине стала неактивна. Проверить можно выполнив следующий t-sql запрос:
select cpu_id, status, is_online from sys.dm_os_schedulers
Статус VISIBLE OFFLINE свидетельствует о неактивном состоянии ядра/потока, т.е. никакие пользовательские запросы не обрабатываются данным ядром. Статус VISIBLE ONLINE свидетельствует о активном состоянии ядра/потока, т.е. пользовательские запросы обрабатываются данным ядром. Более подробно о статусах можно узнать в описании DMV – sys.dm_os_schedulers.
После корректной активации SQL-сервера не д.б. ядер со статусом VISIBLE OFFLINE.
Итак, мы определили, что основная нагрузка исходит от процесса SQL-сервера.
Далее предположим, что к высокой нагрузке могли привести запросы, выполняемые в конкретных сессиях.
Наиболее тяжелые запросы и сессии можно определить следующими способами:
Пример запроса, использующего эти динамические представления:
SELECT TOP(15) total_worker_time/execution_count as AVGCPU, ST.[text], QP.query_plan FROM sys.dm_exec_query_stats QS CROSS APPLY sys.dm_exec_sql_text(QS.[sql_handle]) ST CROSS APPLY sys.dm_exec_query_plan(QS.plan_handle) QP ORDER BY AVGCPU DESC
Результат:
Таким образом, имеем запрос который тратит ресурсов CPU на порядок больше всех остальных. Далее можем использовать план запроса для дальнейшего анализа, который может выявить проблему с индексами, статистикой и т.д.
Согласно документации Microsoft при первоначальной выборке из sys.dm_exec_query_stats могут быть неточности в результатах. Для повышения точности рекомендуется выполнить запрос повторно.
Результат:
Итак, получив SPID конкретной сессии, которая нагружает ваш SQL, в случае необходимости можно эту сессию принудительно завершить.
В случае, если первые шаги не принесли никакого результата, то следующим вариантом, требующим проверки является проверка параметра Degree of Parallelism (DOP).
Если кратко, то это настройка отвечает за то, на сколько ядер может быть распараллелен запрос. Чем сложнее запрос, тем выгоднее его распараллеливать на большее число ядер процессора. С другой стороны, когда большая часть запросов простые (а именно так в большинстве своем в системе DIRECTUM), то необходимости в распараллеливании нет. Стоит учитывать, что при установке DOP=1, тяжелые запросы будут выполняться медленнее.
Изменение данной настройки не требует перезапуска SQL-сервера.
Оценить влияние можно так:
select top 25 * from sys.dm_os_wait_stats order by wait_time_ms desc
Наличие в топе CXPACKET как раз и будет говорить о проблемах с параметром DOP.
Эмпирически можно подобрать наиболее подходящее значение DOP для каждой конкретной системы.
В случае, если первые три шага по-прежнему не выявили проблемы с высокой нагрузкой на SQL-сервер, то наиболее вероятная причина в запросах, используемых в системе. И с точки зрения администратора системы вряд ли можно как-то повлиять на ее производительность. Примером этого может служить большое число компиляций/ре-компиляций при использовании непараметризированных запросов, описанных в статье Серия статей. SQL внутри. Статья первая. Компиляция запроса.
Анализ нагрузки на SQL-сервер нужно проводить комплексно, а именно:
Статья интересная, только вот мне интересно стало, как вы такой сервер загрузили? Это сколько пользователей у вас?
Владимир, спасибо за положительный отзыв.
С ситуацией описанной в Шаге 1, столкнулись на одном из нагрузочных тестирований. Использовалась специфичная, весьма тяжелая прикладная разработка, но даже с ней на такую загрузку система выходила при показателе 6-7 тыс. пользователей.
Спасибо большое, у нас как раз SQL сильно грузит CPU.
Дополню статью:
в некоторых случаях при переходе на SQL 2012 резко возрастает нагрузка на CPU (процессор) SQL-сервера. Связано с наличием дефекта в SQL Server 2012, который проявляется в определенных ситуациях при большом числе компиляций.
Проблема устраняется установкой hotfix-а для SQL 2012 - https://support.microsoft.com/en-us/kb/2928300#/en-us/kb/2928300
Данное исправление также входит в Cumulative Update для SQL Server 2012.
Спасибо, помог совет с паралелизмом
Руслан, рекомендацию с параллелизмом можно немного переформулировать:
MAXDOP лучше ставить в соответствии с числом CPU на сервере (у MS есть конкретные рекомендации), при этом "поиграться" с параметром cost threshold for parallelism, тем самым найти золотую середину между загрузкой оборудования и производительностью отдельных запросов/операций.
Сейчас при MAXDOP=1 загрузка CPU минимальна, но длительность отдельных видов запросов м.б. выше, чем при распараллеливании.
Авторизуйтесь, чтобы написать комментарий