В течение нескольких месяцев мы сталкивались с проблемой, когда база данных, которая обслуживает два веб-сервера, загружает ЦП до 100% и остается там часами, если мы позволим. Все 6 процессоров. Это происходит каждые несколько дней в разное время дня. Использование ЦП связано с sqlserver.exe.
Это , а не общая проблема производительности SQL Server («как сделать мои запросы более эффективными»). При возникновении инцидента ЦП снижается с обычных 20% до 100% и остается там до перезагрузки сервера.
Мы находимся на SQL Server 2016 SP2 накопительное обновление 6.
Мы добавили некоторую регистрацию и видим, что во время последнего инцидента с ЦП число спин-блокировок на OPT_IDX_STATS увеличилось до 5775813 спинов за столкновение. Не уверены, является ли это причиной или симптомом?
Before CPU 100% incident
name collisions spins spins_per_collision sleep_time backoffs
---- ---------- ----- ------------------- ---------- --------
OPT_IDX_STATS 787 200250 254.4473 0 5
LOCK_HASH 2137398 630970500 295.205 1410 52938
1 minute later
name collisions spins spins_per_collision sleep_time backoffs
---- ---------- ----- ------------------- ---------- --------
OPT_IDX_STATS 12 69309750 5775813 7 27
LOCK_HASH 17292 49187101 2844.5 47 555
Мы видим около 40 запущенных запросов, когда намекает на инцидент. Как правило, они являются экземплярами тех же двух запросов LINQ. Ни у одного запроса elapsedMS не превышает 20 000 мс, поэтому это не длительный запрос, который разрушает процессор. Это дорогостоящие запросы, но, похоже, это признак проблемы, а не причина - мы видим, что эти запросы накапливаются, потому что БД работает так медленно, потому что ЦП слишком высок. Те же самые запросы (наряду с другими) выполняются все время, в том числе после перезагрузки сервера БД, и они не вызывают проблем после перезагрузки.
На сервере имеется 36 ГБ памяти, и мы не видим, чтобы использование превышало 22%.
Некоторая другая интересная информация: уничтожение текущих запущенных запросов позволяет сбросить ЦП, но ненадолго (запускается снова, когда веб-серверы отправляют больше запросов). Приостановка базы данных для завершения запросов позволяет процессору сбрасываться до тех пор, пока он находится в режиме паузы, но затем он запускается при возобновлении работы базы данных. Перезагрузка сервера базы данных всегда устраняет проблему. До и после перезагрузки базы данных веб-серверы должны отправлять одинаковые типы запросов, что указывает на проблему с SQL Server - в противном случае, почему перезагрузка решит проблему?
Обновление: я написал сценарий PowerShell, который очищает кэш плана, если ЦП> 95% в течение 45 секунд, и это, похоже, решило проблему. Все еще не знаю, в чем проблема.