История одной миграции с SQL Server 2012 на SQL Server 2016+ в системе Microsoft Dynamics AX 2012

Microsoft SQL ServerERP-системы
Spoiler

Всем привет!

На первый взгляд в 2020-ом году тема может показаться не актуальной. Но версия Axapta 2012 еще достаточно популярна, и многие проекты до сих пор активно развиваются на этой версии. Кроме того, информация из топика будет полезна и для тех, кто мигрирует на новейшую версию Dynamics 365 FO.

Предпосылки

Мы около 4 лет успешно эксплуатировали связку MS Dynamics AX 2012 R2 с MS SQL Server 2012 SP3. Но в новых версиях SQL Server появился ряд новых фич, которые мы хотели внедрить у себя (например, Query Store). Плюс жизненный цикл версии 2012 подходит к концу в 2022-ом году. Поэтому, переборов инженерный принцип «работает – не трогай», мы решили мигрировать нашу базу данных на более свежую версию СУБД.

На момент старта проекта уже достаточно зрелой была версия SQL Server 2017, и недавно вышла версия 2019. Но у нас накладывались ограничения версией нашего прикладного софта Dynamics AX 2012 R2. Microsoft гарантировал его стабильную работу только с версией 2016. Поэтому мигрировали на версию SQL Server 2016. Но план миграции и грабли, которые мы собрали по ходу дела, будут актуальны и при миграции на более старшие версии для MS Dynamics AX 2012 R3 и Dynamics 365 FO.

План миграции

Наша система работает в режиме 24\7. Поэтому роскоши большого времени простоя для миграции у нас не было. Нужно было придумать сценарий миграции с минимальным простоем и минимальными рисками. Благо, на тот момент у нас уже был развернут отказоустойчивый кластер на базе Always on. И это сильно упрощало задачу и позволяло провести миграцию с простоем сервиса около 5 минут и возможностью быстрого отката на старую версию, в случае выявления проблем на продакшн на новой версии.

План был такой:

Задача

Длительность

1

Подготовка

a. Выполнить бэкап всех баз на всех репликах (проверить наличие резервных копий)

10 минут

b. Выполнить CHECKDB для всех баз

12 часов

2

Остановить бэкапы на всех репликах

10 минут

3

Отключить автоматический переезд в конфигурации группы доступности

10 минут

4

Обновление вторичной реплики с асинхронной фиксацией (2 перезагрузки).

45 минут

5

Проверка синхронизации группы доступности с обновленной репликой

10 минут

Если базы реплики не синхронизируются см. план отката п.1

6

Обновление вторичной реплики с синхронной фиксацией (2 перезагрузки)

45 минут

7

Проверка синхронизации группы доступности с обновленной репликой

10 минут

Если базы реплики не синхронизируются см. план отката п.1

8

Выполнение вручную планового перехода на вторичную реплику с синхронной фиксацией для группы доступности Always On

Простой 5 минут

9

Проверка синхронизации группы доступности

10 минут

Если базы реплики не синхронизируются см. план отката п.1

10

Проверка работоспособности системы

24 часа

Если обнаружены сбои в работоспособности системы см. план отката п.2

11

Точка невозврата! Обновление локального экземпляра реплики, на котором ранее размещалась первичная реплика (2 перезагрузки)

45 минут

12

Проверка синхронизации группы доступности

10 минут

Если базы реплики не синхронизируются см. план отката п.1

13

Выполнение вручную планового перехода на реплику, на которой ранее размещалась первичная реплика

Простой 5 минут

14

Проверка синхронизации группы доступности

10 минут

Если базы реплики не синхронизируются см. план отката п.1.

15

Включение автоматического переезда в конфигурации группы доступности

10 минут

16

Повышение уровня совместимости баз данных до 2016

10 минут

План отката

1

Сбой в работе группы доступности

1. Удалить вторичную реплику из группы доступности

10 минут

2. Подключиться к вторичной реплике и выполнить восстановление баз данных и журналов транзакций из резервных копий с опцией WITH NORECOVERY

12 часов

3. Добавить вторичную реплику в группу доступности

10 минут

2

Сбои в работоспособности системы

1. Выполнение вручную планового перехода на реплику, на которой ранее размещалась первичная реплика

Простой 5 минут

2. Удалить обе вторичные реплики из группы доступности

10 минут

3. Переустановка экземпляра SQL Server на вторичной реплике с синхронной фиксацией

a. Установить SQL Server с дистрибутива и выбрать те же опции установки, что использовались при установке оригинального экземпляра SQL Server

1 час

b. Выполнить восстановление баз данных и журналов транзакций из резервных копий с опцией WITH NORECOVERY

12 часов

c. Добавить вторичную реплику в группу доступности

10 минут

4. Повторить пункт 2 для реплики с асинхронной фиксацией.

Сложности

До пункта 11 у нас оставалась возможность все откатить назад, на случай если возникнут какие-то непредвиденные сложности, не выявленные при тестировании. Но миграция прошла гладко, с минимальным простоем.

Проблемы начались спустя несколько часов после переключения. То тут, то там стали возникать не объяснимые подвисания системы. Быстрый анализ ситуации показал, что причина зависаний была в странных, не адекватных планах запросов. Оптимизатор предлагал использовать странные индексы для выборок. Иногда даже подбирал индексы, в составе которых не было ни одного поля из критериев выборки. При этом в лабораторном нагрузочном тестировании таких аномалий замечено не было.

А тем временем, у нас в системе, по сути, работает конвейер из различных пакетных заданий. И если одно из заданий «буксует», задерживаются все идущие за ним. А это в свою очередь приводит к нарушению ритма заказа товара поставщикам, отгрузок товара на наш РЦ и так дальше по цепочке. И вот этот «конвейер» стал периодически замедляться, а иногда даже приостанавливаться. Нужно было оперативно искать и устранять причину аномалий.

Первым делом, запустили обновление статистики по самым проблемным таблицам. Не помогло. Запустили ребилд некоторых индексов – тоже эффекта ноль. Все осложнялось тем, что проблема была плавающая и не наигрывалась на тестовых средах.

По ходу поисков причин обнаружили, что в новых версиях SQL Server часть trace flag – ов переехала на уровень базы данных. И часть флагов из рекомендуемых MS перестала работать. Мы активировали эти флаги на уровне БД. Но тоже особых улучшений не было.

Ситуация накалялась. Последняя надежда была на обратное переключения уровня совместимости базы данных на 2012-ую версию. Но тут, о чудо!!!, мы случайно наткнулись на инфу о довольно радикальном изменении в механизме работы оптимизатора, начиная с версии SQL Server 2014. Речь шла о, так называемой, оценке кардинальности.

Это оценка предполагаемого числа строк, которое будет обработано тем или иным оператором запроса. Оценка – один из ключевых факторов при построении плана запроса. Оценку числа строк осуществляет компонент Cardinality Estimator. Так вот, этот компонент практически не менялся еще с версии SQL Server 7.0.

Но, начиная с SQL Server 2014 у сервера появилась новая модель оценки строк. Эта модель оценки имеет новую архитектуру, расширяема и дополняема, версия этой модели получила номер 120 (по аналогии с уровнем совместимости БД, соответствующим серверу 2014 – 120). В 2016 сервере современная модель была расширена и получила номер версии 130, при этом версия 120 сохранилась

Причина в таком радикальном изменении была в том, что со временем, разработчики SQL Server поняли, что старую модель больше развивать нельзя – ее трудно расширять, трудно тестировать. Кроме того, те предположения о реальности, которые были верны во времена SQL Server 7.0, сейчас устарели.

Устарели, но не для Аксапты. Код приложения и движок построителя запросов начинал писаться еще в далеких 90-ых. И за это время был разработан огромный пласт бизнес логики, который так сходу не перекроишь под новую версию оптимизатора.

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

Как только мы это сделали, база снова «полетела».

Ради интереса, мы посмотрели, как обстоят дела с этим параметром в новейшей версии D365 FO. И, как в общем то и ожидалось, там все без изменений. Даже для Azure SQL необходимо активировать старую модель, чтобы избежать проблем с кривыми планами запросов. При переходе со старой версии нужно не забыть про этот параметр. Он, действительно, радикально влияет на быстродействие.

Выводы

Продукты MS развиваются неравномерно. Нужно быть всегда начеку. Часто бывает так, что новейшие версии каких-то из компонентов экосистемы плохо дружат с текущими версиями других компонентов. Нужно тщательно изучать change log новой версии любого продукта перед upgrade-ом.

Теги:microsoft dynamics ax 2012microsoft dynamics 365 fo
Хабы: Microsoft SQL Server ERP-системы
+6
1,1k 10
Комментарии 2

Похожие публикации

Оператор технической поддержки
от 25 000 ₽АвтотрейдИркутск
Разработчик MS SQL
от 160 000 ₽ТакскомМосква
Senior .NET Backend Developer
от 160 000 до 240 000 ₽WebmercsСамара
Senior .Net Developer
от 170 000 ₽e-POSМожно удаленно

Лучшие публикации за сутки