Интересный случай из практики с Failover-ом SQL Server.

Как то я столкнулся с проблемой, которую мне потом удалось смоделировать. Вот об этом и пойдет речь в данной статье.

Суть проблемы состоит во внезапном перекате ресурсной группы SQL Server на другой узел. Все это произошло без видимых причин.

Я начал разбираться с проблемой, и она показалась мне очень интересной, хотя она и не нова, а скорее типична.
Первое, что я подверг анализу, был кластерный лог. Я обнаружил в нем информацию о невозможности в 10:34:05 (время смоделировано) соединиться с SQL Server.

1.jpg

Обратите внимание на первое сообщение. Суть его состоит в том, что sqsrvres.dll не может возвратить какой-то столбец с SQL Server. Возникает, вопрос, что за столбец и зачем он понадобился. Вот тут необходимо немного теории из области кластеризации SQL Server.

Как работает проверка исправен или нет SQL Server?

Начина я с версии SQL Server 2012 алгоритм проверки изменен, он стал более сложным и более глубоким. Подробно об этом можно прочитать здесь https://docs.microsoft.com/en-us/sql/database-engine/availability-groups/windows/flexible-automatic-failover-policy-availability-group?view=sql-server-2017.

Вкратце, это выглядит, так. Если у вас на кластере включен FailureConditionLevel равный как минимум 2, а по умолчанию он включен на уровне 3, то кроме двух стандартных проверок работоспособности SQL Server (характерных для уровня 1 и 2) добавляется еще одна, это выполнение на сервере хранимой процедуры sp_server_diagnostic. Данная ранимая процедура должна в период времени не превышающий HealthCheckTimeout "успеть" выполниться и возвратить результирующий набор о работе основных компонент сервера. Если же эта хранимая процедура не выполнится в интервал времени HealthCheckTimeout, то SQL Server считается не работоспособным, что приведет  к выполнению  процедуры Failover для роли SQL Server.

2.jpg

Последовательность выполнения проверки такая:

  1. Один раз в 60 секунд кластерная служба (ClusSvc) работающая по аккаунтом NT Authority\SYSTEM инициирует выполнение проверки работоспособности ресурса называемой "Thorough Check".
  2. Этот запрос передается процессу RHS.EXE, а он распространяет его на все процессы находящиеся у него внутри (RHS.EXE это контейнерный процесс кластера).
  3. RHS.EXE вызывает кластерную библиотеку sqsrvres.dll, которая и выполняет проверку исправности SQL Server в соответствии с политикой установленной администратором.
  4. SQLSRVRES.DLL от имени NT Authority\SYSTEM вызывает хранимую процедуру sp_server_diagnostic. Для того, чтобы выполнение данного запроса было возможно на SQL Server создается логин для имени NT Authority\SYSTEM, имеющий минимальные полномочия.

Поскольку произошел перекат ресурсов из-за невозможности выполнить запрос в установленное время, первое, что я проверил, а существует, ли такой логин. Ответ – да, он существует и имеет соответствующие разрешения.

Вторая причина, которая могла бы привести к подобной проблеме – это что-то, что связано с производительностью.

Я начал анализировать все логи SQL Server из папки …Mssql\Log. В *.trc трассах, я обнаружил, что накануне этого времени были запущены запросы, которые вызвали огромное количество событий HASH WARNING и SORT WARNING, а именно хеширование и сортировка (наряду с компиляцией и рекомпиляцией) одни из основных причин перегрузки процессоров, это очень процессоро-потребляющие операции (в данном случае запросы я смоделировал).

3.jpg

Далее мой путь был в Performance Monitor, и он да ответ.

Как видите все процессоры системы именно в этот момент времени были загружены на 100%, а “злодеем”, т.е потребителем был процесс sqlservr.exe он потребил все процессоры на 100%.

4.jpg

Далее последует рекомендация заняться оптимизацией запросов, приводящих к такой ситуации, или выделении ораниченных ресурсов для этих запросов, используя Resource Gopvernor.

До новых встреч. Рад если эта статья была интересна для вас.

 

Александр Каленик, Senior Premier Field Engineer (PFE), MSFT (Russia)