Почему нам так важно понимать различия между редакциями SQL Server Enterprise и Enterprise Core? Дело в том, что использование сервера зависит от того, какую редакцию вы установите. Недавно мне пришлось работать с клиентом, выполнявшим перенос рабочей среды из SQL Server 2012 в SQL Server 2016. Десяток задействованных серверов были подготовлены за несколько недель и даже месяцев до миграции, а многократно протестированный с неизменным успехом план был следующим:

  1. Использовать доставку журналов, чтобы синхронизировать различные серверы непосредственно перед точкой миграции.
  2. Запретить подключение пользователей.
  3. Выполнить все необходимые подготовительные задачи как на платформе данных, так и на уровне приложений.
  4. Произвести и применить окончательное резервное копирование журнала.
  5. Обновить установку совместимости до 2016 (130).
  6. Выполнить некоторые стандартные тесты, а затем вернуть всех пользователей в среду.

Собственно процесс занял немного больше времени — это происходит всегда, когда приходится иметь дело с реальными подключениями, но в остальном все прошло безупречно.

Затем мы начали замечать неполадки с рабочими потоками, когда среда вернулась к пиковой нагрузке. Было упущено что-то, проявлявшееся при полной нагрузке на среду. В этой статье я расскажу, что мы обнаружили и как устранили неполадки.

Первые признаки

Вскоре после того как пользователям было позволено вернуться в среду SQL Server, мы начали замечать проблемы, связанные с высокой нагрузкой на процессор; при этом, согласно данным программ мониторинга, ресурсы процессора были использованы лишь на 50%. Также нам показалось странным, что нагрузка процессора, похоже, не распределялась поровну между всеми 72 ядрами на сервере. Это привело к неравномерности NUMA, как показано на экране 1. Как можно заметить, этот сервер потреблял почти 100% ресурсов процессора у 40 используемых ядер, но остальные 32 ядра были практически нетронутыми. Подсчитав, мы выяснили, что показатель 56% измерен по всем ядрам, независимо от того, задействованы они или нет. Но сервер был на 100% использован у 40 ядер, которые он мог задействовать.

 

Неравномерная загрузка ядер процессора
Экран 1. Неравномерная загрузка ядер процессора

 

Вопрос в том, почему SQL Server использует только 40 ядер, если в распоряжении сервера их 72?

Мы начали искать дополнительную информацию. На мой взгляд, «дополнительная информация» в отношении SQL Server обычно означает обращение к динамическим объектам управления (http://thesqlagentman.com/periodic-table/), или сокращенно DMO. Чтобы собрать больше сведений о том, как ядра выглядят для SQL Server, я использовал запрос к DMO sys.dm_os_schedulers для проверки подсчетов, сгруппированных по статусу:

SELECT OS.status, COUNT (OS.status)
FROM sys.dm_os_schedulers AS OS
GROUP BY OS.status
ORDER BY OS.status;

Результаты не внушали оптимизма (см. экран 2). Что именно они означают? На уровне метаданных результаты показывают, что есть 40 планировщиков, которые удалось задействовать службе SQL Server (VISIBLE ONLINE), но существуют и дополнительные планировщики, недоступные в их текущем состоянии. К ним относятся планировщики HIDDEN, которые используются для обслуживания рабочих нагрузок системного уровня и недоступны для запросов конечных пользователей (подсчеты для HIDDEN ONLINE были приемлемыми и ожидаемыми в соответствии с их особыми характеристиками), а также единственный планировщик VISIBLE ONLINE (DAC), зарезервированный для выделенного подключения администратора (DAC). Остаются 32 планировщика, перечисленные как VISIBLE OFFLINE, которые должны быть доступны для рабочих нагрузок конечного пользователя, но на самом деле недоступны. Планировщик VISIBLE OFFLINE, хотя и адресуемый, не может взаимодействовать с рабочими нагрузками SQL Server, по крайней мере, по одной причине. Такого регулирования загрузки процессора мне не приходилось встречать за те 20 лет, что я работаю администратором баз данных и преподавателем, в том числе в статусе MVP.

 

Результаты запроса к DMO sys.dm_os_schedulers
Экран 2. Результаты запроса к DMO sys.dm_os_schedulers 

 

Интересно, что эта же проблема наблюдалась на всех серверах, задействованных в переходе на SQL Server 2016: все ограничены 40 ядрами с технологией Hyper-Threading, то есть использовалось 20 ядер. На данном этапе несколько человек вспомнили о блоге Джона Морхауса, Data Platform MVP. В одной своей публикации (http://sqlrus.com/2017/03/schedulers-to-rule-them-all/) он отмечал, что столкнулся в SQL Server 2012 с похожей проблемой, связанной с лицензированием.

В сущности, причиной недостаточного использования сервера была установка неверной редакции Microsoft SQL Server 2016. Поскольку высока вероятность, что один набор установки использовался для всех серверов, становится ясно, почему на всех серверах возникала одна и та же проблема. Позвольте мне объяснить.

Два возможных варианта установки для Enterprise Edition

Существует две возможные причины, ведущие к установке неверной редакции Enterprise Edition SQL Server 2016:

  1. Изменения в порядке лицензирования для SQL Server, вступившие в силу в 2012 году.
  2. Склонность компании Microsoft к использованию похожих названий для разных технологий или компонентов.

В 2012 году Microsoft изменила подход к лицензированию SQL Server, начав выдавать лицензии в зависимости от ядер. Это привело к ветвлению вариантов установки SQL Server как на основе клиентских лицензий, так и в зависимости от числа ядер. Лицензирование само по себе очень глубокая тема, и она выходит за рамки данной статьи, но это решение имело важные последствия, так как возникло два различных варианта установки исполняемых файлов.

Кроме того, Microsoft нередко переопределяет акронимы и термины, относящиеся к различным продуктам (а в случае с DAC — в рамках одного продукта). В этом случае возникает путаница вокруг термина «ядро». Дело в том, что существует также редакция Server Core операционной системы Microsoft Windows без графического интерфейса, на которой можно установить SQL Server. Процесс установки на Windows Server Core описан здесь: https://docs.microsoft.com/en-us/sql/database-engine/install-windows/install-sql-server-on-server-core. На экране 3 ясно видно, что человек, выбиравший продукт для установки, неверно воспринял редакцию Core для SQL Server 2016 как редакцию, предназначенную для Windows Server Core, а не как слово core, относящееся к SQL Server, от которого и происходит определение лицензирования в зависимости от количества ядер.

 

Варианты установки SQL Server 2016
Экран 3. Варианты установки SQL Server 2016 

Из приведенных на экране 3 вариантов, взятых со страницы загрузки Microsoft MSDN, видно, как могло возникнуть такое недоразумение.

Почему я подробно остановился на теме редакций SQL Server Enterprise и Enterprise Core? Потому что если выбрана редакция, не отмеченная явно как Core, то вы устанавливаете редакцию SQL Server с лицензией Server+CAL, ограниченной 20 или 40 ядрами при использовании технологии Hyper-Threading.

Теперь становится ясно, откуда берутся 40 планировщиков VISIBLE ONLINE и почему 32 остаются неадресуемыми, хотя они видимы. Причина в том, что по условиям лицензирования эти ядра не могут быть задействованы в службе. Первое впечатление угнетает: мысль о необходимости пройти по всей новой миграции на уже используемом оборудовании, чтобы получить «верные» редакции для SQL Server. Представьте эти и другие панические мысли, и вы получите представление о настроении участников процедуры миграции.

Однако существует и более простой способ решить проблему с лицензированием, которому одновременно помогает и мешает базовая архитектура высокой доступности, развернутая на этапе обновления и миграции: распределенные группы доступности Distributed Availability Groups (DAG).

Сложности распределенных групп доступности

Группы доступности представляют собой развитие технологий высокой доступности и аварийного восстановления (HA/DR) в виде зеркального отображения базы данных и кластеризации серверов.

Группа доступности (AG) состоит из двух или нескольких серверов («реплик»), которые являются узлами отказоустойчивого кластера Windows Server Failover Cluster (WSFC), и не использует общих ресурсов хранилища, как в случае с типичным WSFC.

Вместо этого WSFC используется группами доступности как фундамент для высокой доступности операционной системы, освобождая множество серверов от «владения» службами SQL Services. Однако, поскольку общее хранилище не задействовано в этой архитектуре (где кластеризованный экземпляр SQL Server размещен в общем хранилище), данная архитектура содержит несколько копий базы данных, являющейся частью AG, а не единственную копию, как при зеркальном отображении базы данных. Но, в отличие от зеркального отображения базы данных, любая из этих реплик базы данных доступна для чтения, а одна доступна как для чтения, так и для записи. Это очень упрощенное описание архитектуры групп доступности, но главное, что это архитектура, в которой применяется кластеризованный набор серверов, взаимодействующих друг с другом для обеспечения работы SQL Server.

Отступление о группах доступности уместно, поскольку, как и кластеризованный экземпляр SQL Server, любое исправление должно быть в первую очередь применено ко вторичной (неосновной) реплике, или экземпляру, или узлу, за которым следует переключение для смены владения, с тем чтобы применить исправление к прежнему основному узлу. Наше исправление для решения проблемы регулирования загрузки процессора должно применяться к обоим серверам в группе доступности, а таких групп три.

Как часто говорят в рекламе, и это еще не все. Это верно в случае с нашей архитектурой, так как мы имеем дело не просто с группами доступности, а с распределенными группами доступности.

Что такое распределенная группа доступности (DAG)? Это группа доступности, состоящая из групп доступности, которые используются, чтобы разрешить геораспределенные реплики AG в центрах обработки данных. Таким образом, например, обеспечивается аварийное восстановление и избыточность сайтов. В группе доступности необходимо обратить внимание на задержку между всеми репликами. Группы доступности, как и при Database Mirroring, могут быть настроены как синхронные или асинхронные. Для первого варианта требуется, чтобы все транзакции на первичной реплике были зафиксированы на вторичной реплике, прежде чем они будут зафиксированы на первичной. Последнее подразумевает, что в конечном счете будет достигнута согласованность между репликами, и устраняет требование двухфазной фиксации из схемы архитектуры.

Даже в случае с асинхронной фиксацией сохраняется насущная необходимость малых задержек в очередях, служащих каналом связи между двумя репликами. Этого трудно добиться при наличии географически разделенных реплик, поэтому, вместо того чтобы задействовать AG с «удаленными» репликами, используется DAG. В распределенной группе доступности вы получаете две группы доступности, по одной для центра обработки данных. В любой момент времени одна AG владеет DAG, а в первичной AG имеется первичная реплика, которая владеет AG и, по умолчанию, связанным DAG. По крайней мере, вы получите четыре реплики, из которых одна первичная и три вторичные. Теперь исправление нужно применять не к одному экземпляру SQL Server, как в автономной среде, а к двум экземплярам вследствие групп доступности и затем к четырем экземплярам, поскольку мы имеем дело с распределенными группами доступности. Наконец, умножьте результат на три отдельных DAG вследствие внутренней структуризации среды SQL Server, и мы получим 12 исправлений вместо одного. Теперь становится понятно, почему полное перестроение производственной системы в процессе миграции — неприемлемый вариант.

Решение

Последствия устранения этой проблемы оказались значительно менее серьезными, чем мы первоначально предполагали. В основе лежит процесс, обеспечивающий обновления редакции от Standard Edition до Enterprise Edition, интегрированный в мастер установки SQL Server. Возможен переход от лицензирования Server + CAL к лицензированию по количеству ядер с использованием одной инструкции командной строки. Процесс выглядит следующим образом:

1. Загрузите нужную версию файлов установки.

2. Смонтируйте файл iso для установки и запустите файл setup.exe.

3. Укажите PID — другое имя для ключа безопасности, состоящего из букв, знаков переноса и цифр.

4. Отмените установку.

5. Запустите окно командной строки cmd с правами администратора.

6. Перейдите в каталог, где находится файл setup.exe для загруженного и смонтированного носителя.

7. Подставьте значение PID в следующую команду:

Setup.exe/q/ACTION=editionupgrade/
   INSTANCENAME=MSSQLSERVER/
   PID=XXXXX-XXXXX-XXXXX-
   XXXXX-XXXXX/
   IACCEPTSQLSERVERLICENSETERMS

8. Нажмите клавишу Enter и подождите. Выполняется обновление редакции, которое представляет собой замену метаданных, но может занять несколько минут и заставить нервничать даже самых терпеливых администраторов баз данных. Процесс завершится, когда на экране вновь появится командная строка.

9. Отсоедините файл iso и удалите ненужные файлы.

Эта команда изменяет модель лицензирования и освобождает планировщики VISIBLE OFFLINE, в сущности удалив ограничение по регулированию ресурсов процессора (экран 4).

 

Ограничение по регулированию ресурсов процессора снято
Экран 4. Ограничение по регулированию ресурсов процессора снято

Как показано на экране 5, была решена и проблема разбалансировки NUMA.

 

Равномерная загрузка ядер
Экран 5. Равномерная загрузка ядер

Мне пришлось выполнить эти действия в первую очередь на вторичной реплике вторичной AG, а затем переключиться на вторичную группу доступности и выполнить ту же команду на бывшей первичной реплике. Затем процесс повторяется в группе доступности, которая владеет DAG. Процесс приводит к перезапуску SQL Services в рамках применения исправления, но, поскольку ни в один момент времени я не исправлял первичную реплику, конечные пользователи не заметили никаких последствий, кроме обычных при переключении группы доступности.

Впоследствии обновление было весьма успешным. Переход от SQL Server 2012 к 2016 привел к уменьшению задержек, повышению общей производительности и возможности начать использовать хранилище запросов Query Store и другие компоненты SQL Server 2016. Настало время начать планировать переход на SQL Server 2017!