В деятельности любой организации наступает момент, когда проверенная и вполне работоспособная платформа устаревает и требует замены. Причин может быть множество: поставщик прекратил поддержку текущей версии, современное «железо» не в состоянии выдать максимальную производительность, потому что программное обеспечение не умеет с ним работать, бизнес требует таких решений, которые либо невозможно, либо затруднительно реализовать программными средствами десятилетней давности, данных стало слишком много — список можно продолжать.
В результате принимается решение о переходе на новый программный продукт, то есть о миграции, или обновлении.
Если существующая платформа действительно имеет десятилетнюю историю, то может возникнуть искушение перейти не на самую последнюю версию, а на ту, которая была выпущена до нее. Она уже имеет пакеты обновления, накоплен опыт внедрения и эксплуатации. Однако я хочу предостеречь компании от такого подхода.
За и против
В моей статье речь пойдет о программном продукте Microsoft SQL Server, о миграции с версий 2000 (8.0) и 2005 (9.0) на версию 2008 (10.0). Причин, почему не стоит переходить на SQL Server 2005, если сейчас установлена версия 2000, существует несколько:
- SQL Server 2005 вышел в 2005 году, поэтому из отпущенного ему срока поддержки уже прошло более четырех лет. SQL Server 2008 вышел в 2008 году и будет гораздо дольше находиться в зоне полной поддержки.
- Переход с версии 2000 на 2005 по трудоемкости примерно равен переходу сразу на версию 2008. Потом все равно придется переходить на 2008 или на следующую версию, так зачем удваивать затраты на переход?
- Если посмотреть на функциональность версий SQL Server, становится очевидна парность версий 6.0–6.5, 7.0–2000, 2005–2008. В первой версии пары, как правило, появлялась богатая новая функциональность или происходило существенное изменение ядра и основных подсистем. Вторая версия строилась на новой архитектуре и обеспечивала расширение реализованных ранее возможностей, в том числе и скрытых, например структур хранения данных. Так что если затянуть с переходом, то после выхода, скажем, версии SQL Server 2011 окажется, что все настолько изменилось, что переход станет просто невозможным. А пока есть время подтянуть систему до нормального уровня и спокойно ожидать очередную версию.
С чего начать?
Конечно же, с планирования. Редко какая серьезная система работает изолированно, по крайне мере клиентская часть у нее всегда найдется. Она также может взаимодействовать с другими системами, поведение или характер использования которых может оказать существенное влияние на сам процесс перехода или хотя бы на тот интервал, в течение которого переход должен быть завершен.
Часто бывает, что ядро прикладной системы зависит от периферийных компонентов, таких как службы Data Transformation Services (DTS), аналитические службы, службы отчетов и т. п. Все это следует учитывать как с точки зрения оценки времени на переход, так и с точки зрения работоспособности элементов «окружающей среды» совместно с новым реляционным движком базы данных.
Следует тщательно изучить разделы документации, которые описывают несовместимость предыдущих версий. Причем изучение следует начинать со сравнения версии 2000 с версией 2005 (если вы переходите с SQL Server 2000). Дело в том, что документация описывает различия между 2005 и 2008. Но их не так много, а вот различий между 2000 и 2005 гораздо больше, помните, 2005 — первая версия новой пары, а именно эти версии являются революционными.
Утилита Microsoft SQL Server 2008 Upgrade Advisor предназначена для распознавания несовместимостей. Полностью полагаться на нее не стоит, но она способна распознать явные несоответствия, снимая с вас работу по поиску конструкций типа «*=» или подобных. Мастер по обновлению может проанализировать существующую базу данных. Если часть кода создается непосредственно клиентским приложением и посылается на сервер не в виде вызовов хранимых процедур, а в виде индивидуальных команд, то серверу можно передать файл трассировки.
Мастер выведет найденную информацию в отчет и предложит дополнительное описание, позволяющее понять, можно ли с корректировками потерпеть до окончания перехода или несовместимость настолько серьезна, что сначала ее нужно устранить и только потом начинать миграцию.
После всех описанных выше мероприятий можно начать собственно планирование миграции. И первым пунктом плана должно быть тестирование. Чем тщательнее и ближе к реальной жизни будет тестирование, тем больше шансов, что и в промышленной эксплуатации система станет работать, как ожидалось. Верно и обратное утверждение.
Тестирование
Тестировать можно с акцентом на нагрузку и с упором на бизнес-функционал. Думаю, что не ошибусь, предположив, что провести тестирование с упором на бизнес-функционал шансов гораздо больше. Однако это может оказаться серьезной ошибкой. В одном из недавних проектов мы переводили очень сложную систему с высоконагруженной подсистемой исполнения заданий SQL Agent. На тестовом стенде мы «вылизали» до блеска основной процесс перехода, за который боялись больше всего. И он прошел без сучка без задоринки. А вот под промышленной нагрузкой оказалось, что неполное тестирование способно сыграть злую шутку. И здесь мы даже не могли оправдаться тем, что у нас не было возможности имитировать необходимые 1,5 тыс. одновременно работающих заданий. Мы потратили около трех часов, разбираясь с настройками подсистем SQL Agent, пришлось даже открывать инцидент высшей категории в службе премьер-поддержки. А все почему? Потому что тестирование было проведено однобоко.
Как организовать тестирование
В идеальной ситуации в организации имеются и поддерживаются в актуальном состоянии сценарии, которые имитируют нагрузку средствами профессиональных инструментов типа HP Load Runner, или написаны в среде Microsoft Visual Studio. Использование такого подхода позволяет не только организовать на стенде реалистичную нагрузку с точки зрения бизнес-функционала, но и выполнить стрессовую нагрузку с большим числом пользователей. Как мы знаем, SQL Server обслуживает в основном многопользовательские системы, и проверка работы приложения в конкурентной среде очень важна.
Но мы живем в реальном мире, и за всю мою работу консультантом я встретил только одного заказчика, у которого описанный выше подход был реализован на деле, и мы смогли использовать его в миграционном проекте. Как правило, приходится иметь дело с разрозненными сценариями на T-SQL, которые в лучшем случае покрывают только малую часть функций, а о стрессовой нагрузке и говорить нечего. Что же делать?
Использовать то, что есть под рукой, так как совсем без тестирования просто нельзя. Нужно извлечь все, что есть в наличии, отсортировать и выбрать, во-первых, то, что имеет отношение к текущей версии системы, во-вторых, то, что поддается параметризации. Для тех сценариев, которые будут использоваться при тестировании, следует определить параметры, с которыми они должны запускаться. Дальше можно написать процедуры-оболочки, которые будут выбирать случайным образом нужное число имеющихся параметров и запускать с ними соответствующий запрос. Самым сложным будет программирование корректного выбора параметров, особенно если они связаны друг с другом.
Процедуры-оболочки следует вызывать из нагружающего приложения, способного установить соединение с сервером и выполнить на нем указанную команду. Если это эффективный инструмент, он позволит указать задержки, на каком из соединений и что следует делать, если примитивный, то он просто будет посылать команды на сервер, и тогда придется создать оболочку для оболочки, в которой случайным образом выбирается один из нагружающих сценариев и выполняется по описанному выше способу. В качестве средства для нагрузки можно задействовать утилиту ostress из комплекта утилит RML Unitilities или любой свободно распространяемый инструмент.
Если имеющихся сценариев недостаточно, то на помощь приходит трассировка промышленной системы с получением набора TRC-файлов, которые можно использовать для воспроизведения нагрузки. Именно этот вариант мы рассмотрим подробнее.
Трассировка и воспроизведение в тестовой среде
Инструмент SQL Server Profiler способен не только снять трассировку исполнения команд, но и воспроизвести их для имитации нагрузки. Однако я пользовался этим решением с переменным успехом. Если он заработает, то нагрузка на процессор практически постоянно будет составлять 100%, и это независимо от мощности рабочей станции. Но самое неприятное как раз — «если заработает». Мне неоднократно приходилось сталкиваться с ситуацией, когда Profiler считывает только первый файл трассировки, после чего считает работу выполненной. Даже для умеренно нагруженной системы обойтись одним файлом вряд ли удастся.
Я предпочитаю использовать утилиту Readtrace из комплекта RML Utilities for SQL Server, которая умеет:
- очень быстро разбирать файлы трассировки в таблицы — гигабайт трассировок разбирается примерно за минуту;
- на основе содержимого файлов трассировки формировать командные сценарии, которые можно воспроизвести на сервере;
- анализировать данные в файлах трассировки для поиска наиболее нагружающих систему запросов (это полезно при анализе работы уже внедренного приложения).
При работе с Readtrace сначала нужно получить файлы трассировки. Трассировку следует выполнять только на серверной стороне, то есть запуск и определение последовательности команд нужно делать из программы на T-SQL. Большая часть кода описания трассировки состоит из вызовов процедуры sp_trace_setevent — это десятки строк; сразу становится ясно, что вручную такой код писать не стоит. К счастью, сам Profiler облегчает нам задачу. Набрав нужные события и их атрибуты, можно сохранить результаты в файле или шаблоне. Настоятельно рекомендую сделать и то и другое. Файл мы будем использовать для сбора данных, а шаблон позволит не набирать события каждый раз заново.
Полученный из Profiler сценарий с определением трассировки стоит немного доработать, чтобы он умел создавать неповторяющиеся имена файлов, знал, что после завершения одного файла следует начать новый, и умел останавливаться самостоятельно.
Чего можно ожидать с точки зрения объемов? На нагруженной системе легко получить два–четыре TRC-файла размером 350 Мбайт каждый в минуту. Размещать файлы следует в каталог, на котором не хранятся файлы базы данных самого SQL Server; нужно указать антивирусу, что он не должен их проверять, и можно создать сжатый каталог для файлов.
Процесс трассировки должен начинаться непосредственно после снятия полной резервной копии с базы данных. Это позволит избежать ошибок, когда при воспроизведении нагрузки на стенде вы пытаетесь, например, создать уже присутствующую проводку.
Описанный подход не свободен от недостатков, и самый существенный из них состоит в том, что протестировать удастся только те функции, которые попали в трассировку. Все остальное нужно проверять каким-то иным способом.
Обработка полученных данных
После того как трассировка завершена, следует перенести файлы на рабочую станцию с установленным SQL Server версии 2005 или 2008 и обработать их средствами Readtrace.
При разборе TRC-файлов Readtrace создает по одному RML-файлу на каждое соединение, участвовавшее в работе на сервере на период сбора. Имеет смысл посмотреть, кто работал с базой данных, и выкинуть лишние команды, например если есть активное приложение, которое занимается не интересующей нас работой. После такой чистки начинаем подготовку к воспроизведению нагрузки на тестовом сервере. В первую очередь, необходимо восстановить на нем две копии базы данных — для текущей версии сервера и для версии 2008. Затем следует обновить статистику, по возможности с полным сканированием и дефрагментацией индексов.
После того как предварительные операции над базой данных версии SQL 2008 выполнены, ее следует скопировать, чтобы не делать все это каждый раз при повторной установке. Резервную копию обязательно сделайте с компрессией, вы будете приятно удивлены высокой скоростью сжатия и малыми размерами резервной копии.
Теперь обратимся к файлам языка Relational MetaLanguage (RML). Файл RML — это XML-файл определенной структуры. Все файлы содержат блок, относящийся к соединению. Если пользователи работают с доменными учетными данными, тогда проблем не возникнет. Если применяется аутентификация средствами SQL Server, задача усложняется. Дело в том, что утилита ostress, которая используется для воспроизведения нагрузки, способна применить только одно имя учетной записи SQL Server, поэтому придется в явном виде указывать пароли пользователей в теле RML. Для этого в раздел, ограниченный тэгами CONNECT, следует вписать блок
В ходе тестирования мы сначала запускаем воспроизведение для базы данных в среде SQL 2000, потом для базы данных SQL 2008. В обоих случаях, пользуясь тем же сценарием, снимаем трассировку для двух прогонов. После того как прогоны выполнены и трассировка получена, наступает время выяснить, как обстоят дела с производительностью. Об этом речь пойдет во второй часть статьи.
Дмитрий Артемов (dimaa@MICROSOFT.com) — старший консультант серверной практики Microsoft Россия