- PVSM.RU - https://www.pvsm.ru -
Есть информационная система, которую я администрирую. Система состоит из следующих компонент:
1. База данных MS SQL Server
2. Серверное приложение
3. Клиентские приложения
Данные информационные системы установлены на нескольких объектах. Информационная система активно и круглосуточно используется одновременно от 2-х до 20-ти пользователей на каждом объекте. Поэтому нельзя выполнять регламентные работы все и сразу. Т е приходится дефрагментацию индексов размазывать на целый день, а не одним махом все нужные фрагментированные индексы дефрагментировать. Аналогично и с другими работами.
Автообновление статистики выставлено в свойствах самой базы данных. Также статистика обновляется по дефрагментированному индексу.
Около года назад столкнулся со следующей проблемой:
Периодически все запросы выполнялись долго. Причем время торможений были случайными. Это происходило на каждом объекте в случайный день. Более того, когда стал анализировать как часто происходят торможения (профайлером), то удалось выяснить, что они происходят каждый день в случайное время. Просто пользователи не всегда обращают на это внимание, а воспринимают как единственную случайную задержку, и потом система опять быстро работает.
Были пересмотрены сами запросы, которые выполнялись долго. Но самое интересное, это то, что все запросы в случайное время выполнялись долго. Даже самые простые типа вытащить последнюю запись из таблицы в несколько тысяч строк.
Далее, были проведены следующие работы:
В итоге было потрачено более 3-х месяцев на безуспешные поиски причины периодических торможений. Однако, удалось выявить интересный факт – у всех запросов вырастал показатель ожидания Elapsed, а не сам показатель выполнения Worker. Что натолкнуло на то, что возможно что-то с дисками. Тоже их проверил — все нормально.
Удивительным было то, что случайным образом удалось установить, что когда запрос в приложении выполняется медленно, то в самом SSMS он выполняется быстро. Тогда для решения помогла следующая статья [1] (она по крайней мере в последствии натолкнула на идею).
Из этой статьи процитирую следующий абзац:
На практике наиболее важной опцией SET является ARITHABORT, потому что значение по-умолчанию для этой опции отличается для приложений и для SQL Server Management Studio. Это объясняет, почему вы можете обнаружить медленный запрос в вашем приложении, и затем получить хорошую скорость, выполняя его в SSMS. Приложение использует план, который был построен для набора значений отличающегося от актуальных, правильных значений. Тогда как если вы запускаете запрос в SSMS, то вероятнее всего в кэше пока еще не имеется плана выполнения для ARITHABORT ON, и поэтому SQL Server построит план для ваших текущих значений.
Разница в выполнении была в параметре SET ARITHABORT. Для всех запросов, выполняемых в SSMS этот параметр включен, а для запросов из вне (из приложений) – выключен. И его нельзя включить даже простым запросом для приложений:
SET ARITHABORT ON;
После этого последовала безумная идея – в момент зависания очищать процедурный кэш: клик [2].
Для последующей ручной проверки перед запросом в SSMS необходимо писать:
SET ARITHABORT OFF;
Тогда запрос будет выполняться, как если бы он пришел из приложения. Когда запрос выполнялся долго, то я очищал процедурный кэш. И всегда это лечило. Т е до чистки процедурного кэша, запрос мог выполняться до 20-30 секунд, а после – 0 секунд.
После этого был поставлен еще один эксперимент – чистка всего процедурного кэша для всей базы данных каждый час через SQL Agent:
--очищаем кэш по id БД
DBCC FLUSHPROCINDB(@db_id);
После этого все запросы стали просто выполняться очень быстро (менее 0,05 сек.), были лишь единичные выбросы до 5-10 секунд выполнения, но пользователи уже зависаний не замечали. Более того, обновление статистики не улучшало результаты, поэтому я убрал обновление статистики.
После еще нескольких месяцев исследований удалось установить, что единичные зависания происходят, когда на самом сервере либо все съедает кэш, и свободной памяти ничего не остается или остается, но меньше 1 ГБ ОЗУ, либо служба MS SQL Server съедает всю выделенную ей оперативную память (через Диспетчер задач). Но второе происходило всего 2 раза за все исследование.
Дело в том, что в кэш записывается в буквальном смысле все, а вот освобождается кэш не всегда вовремя. Проблему с кэшем удалось решить с помощью программы EmptyStandbyList.exe [3].
Данное приложение настроил через Планировщик задач на выполнение 1 раз каждый час. После проделанных работ уже более полугода нет торможений по запросам на всех объектах.
Единственное, что осталось непонятным, так это редкие случаи, когда один запрос зависнет на 5-10 секунд 1 раз в месяц в случайный день и в случайное время. Всего было за полгода 4 таких случая и то на двух объектах, а не на всех. При этом служба MS SQL Server съедает на короткое время всю выделенную ей оперативную память.
Проделал шаги, описанные в статье [4], но данное решение не помогло.
В принципе можно было и не копать глубже, т к пользователи зависания не замечают и все работает, но если у кого есть какие-то соображения-поделитесь, буду признателен.
Данную статью написал с целью помощи тем, кто наткнется на подобные проблемы, т к комплексного ответа в интернете я не нашел, и было потрачено очень много времени на исследование проблемы и ее решения.
» Раз [5] ⬝ Два [6] ⬝ Три [4] ⬝ Четыре [7] ⬝ Пять [8] ⬝ Шесть [9] ⬝ Семь [1] ⬝ Восемь [2]
Автор: jobgemws
Источник [10]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/administrirovanie-baz-danny-h/204638
Ссылки в тексте:
[1] следующая статья: http://www.somewheresomehow.ru/fast-in-ssms-slow-in-app-part1/
[2] клик: https://msdn.microsoft.com/ru-ru/library/ms174283.aspx
[3] EmptyStandbyList.exe: http://www.downloadcrew.com/article/34150-empty_standby_list
[4] в статье: https://blogs.technet.microsoft.com/sqlruteam/2014/02/09/173/
[5] Раз: http://infostart.ru/public/237919/
[6] Два: https://habrahabr.ru/post/226335/
[7] Четыре: https://social.technet.microsoft.com/Forums/ru-RU/cd60a4a5-4bb4-4ad9-b498-457bdf141c89/windows-server-2008-64-bit-?forum=ws2008r2ru
[8] Пять: http://winitpro.ru/index.php/2016/03/21/vysokaya-zagruzka-ram-metafaylom-na-fajlovom-servere-windows/
[9] Шесть: https://habrahabr.ru/sandbox/83961/
[10] Источник: https://habrahabr.ru/post/313998/?utm_source=habrahabr&utm_medium=rss&utm_campaign=sandbox
Нажмите здесь для печати.