(Возврат на основную страницу)
Сентябрь 2008
№9
(93)
Editorial
Шон МакКоун
21-й знак до рая
Other
Брэд МакГи
Использование монитора производительности. Часть 3
Алекс Кузнецов
Случай искаженных результатов
Рави С. Маньям
Растите вместе с SQL Server 2005 / SQL Server 2008 — NUMA
Алекс Кузнецов
Закрыть дыры в тестировании ваших баз данных
Алекс Кузнецов, Алекс Стайлер
Закрываем дыры: тестирование хранимых процедур
Алекс Кузнецов
Закрываем дыры: стрессовое тестирование хранимых процедур. Часть 1
21-й знак до рая
Хотя я и играл с powershell почти год, мне это средство никогда не казалось серьезным инструментом. На конференции TechED этого года я обратил внимание на некоторые особенно мощные средства, появившиеся в SQL Server 2008, и надо сказать, что мое отношение радикально изменилось, могу даже сказать, что я влюбился (чистая любовь, вы понимаете) в этот инструмент.
Хочу сразу сказать, что способ реализации powershell провайдера в форме миниоболочки вызывает критику. Возможно, эти люди правы. Есть вещи, которые вы не сможете сделать. Я не стану останавливаться на деталях, они достаточно хорошо документированы в блогах. Но я собираюсь рассказать о том, что вы можете сделать с помощью powershell в среде SQL Server. И я не оговорился, когда сказал SQL Server, а не SQL Server 2008.
Дело в том, что вы можете подключиться к любому экземпляру, будь то Yukon или SQL2K и выполнять powershell команды применительно к этому экземпляру. Я думаю, что тут могут быть некоторые ограничения, вроде необходимости иметь как минимум SQL2K SP4 и, возможно, SQL2K5 SP1, но это я оставляю вам на самостоятельное исследование. Идея в том, что вы не ограничены доступом только к SQL Server 2008.
Итак, я не стану нудно перечислять мелкие детали работы, вместо этого я покажу пару примеров.
Чтобы получить список всех таблиц и число записей в них, сначала откройте powershell в SSMS (SQL Server Management Studio) и введите такую команду (я использую Northwind):
cd default\databases\Northwind\tables
Точно так же, как во времена DOS, вы переходите по структуре баз данных, как по папкам.
Теперь:
gci | sort-object -Property RowCount -desc | format-table Schema, Name, Rowcount -autosize
Если кратко, я получаю список таблиц, сортирую их по числу записей в убывающем порядке, вывожу результат в таблицу, в которой будут поля Schema, Name и RowCount. Использование указателя autosize настраивает внешний вид полученного результата. Попробуйте эту команду без параметра autosize и вы сами увидите, что я имел в виду.
Здорово, не правда ли? Вы получаете все таблицы и число записей в них без использования курсора, динамического SQL или временной таблицы. Теперь давайте наложим фильтр. Та же самая команда:
gci *customer* | sort-object -Property RowCount -desc | format-table Schema, Name, Rowcount -autosize
Только теперь вы видите параметр *customer* в ее тексте. Это уточнение говорит, что нас интересуют только таблицы, в имени которых есть строка ‘customer’. Это аналогично условию «like ‘%customer%’» при работе с TSQL.
Пока все прекрасно?
Еще пример, эта возможность меня просто приводит в восторг. Начнем с того же места, вот отсюда:
cd default\databases\Northwind\tables
Теперь введем такую команду:
gci | % {$_.Script()}
Всего 21 символ, что же они делают?
Эта команда создает скрипт для всех таблиц в вашей базе данных, вот что она делает. Никаких курсоров, мороки с окнами графического интерфейса. Просто скрипт каждой таблицы в БД. Прекрасно, не так ли? Вы даже можете вставить эту команду в задание, указать ей график исполнения и так далее. В таком виде, как я показал, она просто выводит текст на экран, стало быть, неплохо бы сделать ее немного полезнее. Давайте выведем результат ее исполнения в текстовый файл.
Итак, все то же самое, только результат идет в файл:
gci | % {$_.Script()} | out-file C:\Table.txt
Вот и все. Точно так же, как и раньше, вы можете указать фильтр для определения области применения команды:
gci *customer* | % {$_.Script()} | out-file C:\Table.txt
Если честно, то для фильтрации есть и более продвинутый объект фильтрации, но это мы оставим на будущее, я просто хотел показать, как это работает.
Серьезно, как это на ваш взгляд? Нет никакой необходимости выполнять все эти операции вручную. Да и сам путь к получению результата стал гораздо короче. Написать программу, которая делает такие же вещи средствами SMO/DMO или SQL окажется гораздо сложнее и проблематичнее. Именно поэтому мало кто берется за эту работу. Но теперь всего 21 символ (включая пробелы) и задача решена. Точно также вы сможете создать скрипт для любого объекта БД, процедуры, представления… Все, что нужно сделать, — это перейти в соответствующий «каталог». И в каждом из них вы сможете сделать ‘dir’, чтобы увидеть, что вы можете сделать.
Я не стану пытаться написать массивное руководство по powershell, моя задача была увлечь вас интересными возможностями. Удачи!
Использование монитора производительности. Часть 3*
*См. Брэд МакГи. Использование монитора производительности. Части 1–2 // SQL Server для профессионалов. 2008. № 7–8.
Если вы хотите получить доступ к данным монитора производительности SQLсервера, но не хотите использовать монитор производительности, вы можете обратиться с запросом к таблице sysperfinfo базы данных master.
Все счетчики производительности SQLсевера могут быть получены из этой таблицы. Это может вам пригодиться, если вы захотите создать хранимую процедуру для получения нужных данных в определенные периоды времени и сохранения этих данных в базу данных SQL Server. Помните, что структура этой таблицы может отличаться в разных версиях SQL Server. (Также следует иметь в виду, что в зависимости от типа счетчика cntr_type получение реального значения показателя, аналогичного тому, что представляет монитор производительности, может потребовать вычислений. Детали см. в http://www.sql.ru/subscribe/2003/149.shtml. — Прим. ред.).
Системный монитор (монитор производительности) запускается через Консоль управления (Microsoft Management Console (MMC)). Поэтому вы можете настроить MMC многими разными способами. Например, вы можете запустить несколько экземпляров системного монитора в одной MMC; это означает, что вы можете следить за разными SQLсерверами на одном экране. Вы также можете добавить системный монитор в любую MMC, включая ту, которую вы используете для администрирования своих серверов.
Если вы хотите создать свою собственную, новую MMC, вы можете это сделать, выполнив строку «mmc.exe». После этого появится пустая Консоль управления, которую вы можете настроить для своих нужд.
Не запускайте монитор производительности из терминальных служб или клиента Citrix. На самом деле, это то же самое, что запустить монитор производительности на том же сервере, за которым производится мониторинг. И, что еще хуже, сервер испытывает дополнительную нагрузку не только изза монитора производительности, но и терминальных служб или клиента Citrix. Вместо этого запускайте монитор производительности на рабочей станции, и соединяйтесь с сервером удаленно.
Не опубликовывайте монитор производительности (системный монитор) в качестве публикуемого приложения Citrix. Данные, полученные от опубликованной версии монитора производительности, могут быть не точны. Вместо этого запустите его на рабочей станции и подключитесь к серверу удаленно.
Если производительность вашего сервера ограничена и вы сделали все, что смогли, для ее увеличения и у вас все еще остаются проблемы с производительностью, вы можете получить «маленький» прирост производительности, запустив SQL Server с использованием ключа x. Эта опция отключает сбор статистики по загруженности процессора и подсчет коэффициента попадания в буферный кеш, уменьшая накладные расходы сервера. Эта опция не позволит монитору производительности работать в полную силу.
При мониторинге активности ввода/вывода, используйте счетчики физического диска, а не логического диска. Счетчики логического диска не всегда предоставляют точную информацию, в особенности при использовании RAIDмассивов.
Периодически собирайте информацию о производительности своих SQLсерверов, а затем сохраняйте эти данные в электронной таблице или базе данных, это позволит вам определять основные тенденции изменения производительности ваших серверов.
Например, вы можете решить собирать данные о своих серверах ежедневно, считывая показания счетчиков каждые 600900 секунд, тогда сохраняйте эти данные в базу данных для анализа тенденций. И хотя для этого нужно приложить определенные усилия, но в результате вы получите целостную информацию, которую можно использовать для планирования будущих апгрэйдов аппаратных средств.
Базовые линии монитора производительности являются ценными инструментами. Одним небольшим полезным свойством базовых линий SQLсервера является возможность определения периодов низкой активности, которые вы, как администратор, сможете использовать с пользой, например для выполнения системных задач, таких как резервное копирование, перестройка индексов и т. д. Иногда периоды низкой активности могут быть очевидны, но в других случаях, такие периоды не столь очевидны. В таких случаях пригодится базовая линия монитора производительности. Проверяя активность в течение периода времени (дня или недели), вы должны легко определить периоды времени, когда активность минимальна.
Воспользуйтесь преимуществом возможности SQLсервера создавать оповещения SQL Server Performance Condition Alerts. Вы можете создавать оповещения, которые будут срабатывать при выполнении заданных вами условий производительности. Например, если вы хотите знать, достигло ли количество пользовательских соединений с сервером 100, вы можете создать соответствующее оповещение, и когда оно сработает, SQL Server может отправить вам электронное письмо с сообщением. Создавайте такие оповещения с помощью SQL Server Enterprise Manager.
Эти оповещения похожи на оповещения, которые вы можете создать с помощью монитора производительности. Но оповещения, создаваемые с помощью Enterprise Manager, более надежны и их легче создавать.
При настройке некоторых приложений, основанных на SQL Server, может пригодиться возможность измерить количество счетов, введенных за час, или количество чеков в час, или, например, количество выполнений определенной хранимой процедуры. Вы можете сделать это и многое другое с помощью монитора производительности. SQL Server содержит объект монитора производительности, названный User Settable Object (пользовательский объект), который является набором из десяти счетчиков производительности, которые вы можете определить для своих целей. Другими словами, вы можете создать до десяти своих собственных счетчиков монитора производительности SQLсервера.
Создать свои счетчики не сложно, если вы знаете, как программировать хранимые процедуры на TransactSQL. SQL Server содержит десять системных хранимых процедур (с именами от sp_user_counter1 до sp_user_counter10) и вы можете определить любое целое значение любому из этих десяти счетчиков. Как правило, одну из этих специальных хранимых процедур инкапсулируют в пользовательской хранимой процедуре, которая используется для вычисления значения, которое нужно передать в счетчик монитора производительности.
Важно понимать, что при создании пользовательского счетчика монитора производительности созданная вами для вычисления значений счетчика хранимая процедура, сама в свою очередь не должна отягощать быстродействие SQLсервера. Старайтесь использовать как можно более простой код в своей хранимой процедуре.
Утилита «Производительность» из состава Windows 2000 содержит возможность, не доступную в более ранних версиях операционной системы. Она позволяет создавать «Журнал трассировки» («trace log»), который используется для сбора информации о ряде событий относящихся к быстродействию. В отличие от «журнала счетчиков», который используется для сбора данных от счетчиков за определенный нами период времени, «журнал трассировки» включает в себя все текущие события, которые возникают за заданный период времени. Эта детальная информация может быть очень полезна для определения очень специфических аппаратных проблем или проблем операционной системы вашего сервера.
К сожалению, сделав легким сбор информации о производительности, Microsoft не позаботилась об упрощении анализа этой информации. Windows 2000 не содержит инструментов для чтения или анализа данных «журнала трассировки». Поэтому вам понадобится Windows 2000 Resource Kit, в котором содержатся две утилиты (Tracedmp.exe и Reducer.exe) для чтения этих данных. Изза этого вы, вероятно, не станете использовать «журнал трассировки» часто. Но если у вас возникла необычная проблема производительности на вашем Windows 2000 SQLсервере, тогда этот инструмент может вам пригодиться, хотя вам и придется затратить дополнительные усилия.
Иногда, по самым различным причинам, счетчики монитора производительности SQLсервера не показываются должным образом. Часто, хотя и не всегда, эта проблема может быть исправлена следующим способом:
В командной строке напишите: unlodctr.exe MSSQLServer;
Затем напишите следующее: lodctr.exe <SQL Server path>\binn\sqlctr.ini;
Перезагрузите сервер.
Если у вас проблема со счетчиками служб анализа (Analysis Services), используйте следующее:
Напишите в командной строке: unlodctr.exe MSSQLServerOLAPService;
Затем напишите: lodctr.exe <SQL Server path>\binn\msmdctr.ini;
Перезагрузите сервер.
Если вы получили сообщение об ошибке, ищите решение на msdn.microsoft.com. Обратите внимание, что данный совет относится только к некластеризованным SQLсерверам.
Как администратор баз данных с опытом в несколько лет, я использую монитор производительности для слежения за состоянием сервера базы данных как на регулярной основе — для анализа тенденций, так и время от времени — для настройки загрузки.
Как отмечено во многих статьях и советах по мониторингу серверов, ввод/вывод — один из самых важных для мониторинга показателей. Я регулярно проверяю дисковый и сетевой ввод/вывод на предмет узких мест возникающих в этих подсистемах.
Одна из проблем: определить, является ли причиной данных операций ввода/вывода SQL Server. Хотя SQL Server должен быть установлен на выделенном сервере, время от времени в дисковой подсистеме возникает активность, которую создает иное чем SQL Server приложение или служба. Неприятным примером такого явления стал для меня системный администратор, использовавший дисковую подсистему SQLсервера для хранения временных файлов.
Счетчик монитора производительности, который я использовал:
Объект — Процесс (Process);
Счетчик — I/Oопераций с данными в секунду (IO Data Operations / sec);
Экземпляр — sqlservr.
Настройте шкалу в мониторе производительности (я использую 0.1), и отношение между операциями ввода/вывода SQLсервера и теми, которые были зарегистрированы в вашей системе, станет очевидным. Когда возникает высокая степень корреляции между счетчиком «Физический диск > Обращений к диску / сек» (Physical Disk > disk transfers / sec) и предыдущим счетчиком, тогда вы можете начинать смотреть, что происходит внутри SQLсервера, чтобы узнать, что можно улучшить. Другие области для поиска — это корреляции между этим счетчиком и сетевым трафиком (неважно: байт/сек или пакетов/сек. Я нашел, что показатель «Сетевой интерфейс > Длина очереди вывода» (Network > Output Queue Length) является очень ненадежным на машинах с SMP, постоянно выводит значение 4294966272 на моем восьмипроцессорном сервере!).
Таким образом, обладание информацией о своем оборудовании — незаменимая, но очень маленькая часть решения этой задачи.
Предыдущий совет был предоставлен Эндрю Престоном (Andrew Preston). Престон был вовлечен в ITиндустрию в Австралии примерно 17 лет назад. В то время он работал системным администратором на системах S/36, AS/400, Netware 2.x, 3.x и 4.x, Wang и NT/2000. Параллельно являясь администратором баз данных и проводя экспертизы запросов на DB2, Focus и SQL Server. На протяжении последних 6 лет он работал консультантом в области электронного документооборота и организации ведения записей, отвечая за разработку и настройку большого числа систем на основе SQL Server, Sybase и Oracle в Австралии, США и Великобритании. В данный момент работает администратором баз данных в организации, расположенной в Канберре. Адрес его электронного ящика agpreston@bigpond.com.
Другой подход к обеспечению быстродействия SQLсервера — с точки зрения очередей. Как вы, возможно, знаете, очередь — это, по существу, некоторый период ожидания выполнения определенной функции, которая по какимлибо причинам не может быть выполнена немедленно.
С точки зрения производительности SQLсервера, очереди это плохое явление, потому что их наличие говорит о том, что определенные функции вынуждены ожидать выполнения. В идеале, нам нужно, чтобы SQLсерверу не приходилось ожидать, мы хотим, чтобы он выполнял свои функции немедленно. Наличие очереди говорит о том, что производительность не достаточна.
Таким образом, один из способов обеспечения быстродействия SQLсервера — это устранение любых найденных очередей. По определению, если мы сможем устранить все очереди, то SQL Server будет работать с максимальным возможным быстродействием.
SQL Server имеет три основных очереди, которые можно отслеживать: очередь ЦП, очередь подсистемы ввода/вывода и очередь сетевого интерфейса. Ниже представлены некоторые ключевые счетчики монитора производительности, которые вы можете использовать для мониторинга за этими очередями.
Система: длина очереди процессора (System: Processor Queue Length);
Физический диск: средняя длина очереди диска (Physical Disk: Avg. Disk Queue Length);
Сетевой интерфейс: длина очереди вывода (Network Interface: Output Queue Length).
В идеале значения этих очередей должны быть в среднем менее 2. Если это не так, тогда вы испытываете проблемы с производительностью и вам нужно установить и разрешить эту проблему. (Для средней очереди на дисках значение должно быть не более 2 на физический диск. — Прим. ред.)
Windows 2000 и Windows 2003 содержат службу журналов и оповещений производительности (Performance Logs and Alerts service). Она используется системным монитором при создании журналов счетчиков, журналов трассировок и оповещений. По умолчанию тип запуска этой службы установлен в значении «Вручную», и она включается автоматически, когда вы используете системный монитор для конфигурирования журналов счетчиков, журналов трассировок или оповещений. Также по умолчанию эта служба запущена от имени локальной системной учетной записи.
Как вы знаете, если вы хотите, чтобы служба одного компьютера имела доступ к другому компьютеру, данная служба должна выполняться под учетной записью доменного пользователя, а не локального пользователя. Это означает, что если вы хотите использовать системный монитор для ведения журналов счетчиков, журналов трассировок или оповещений удаленного сервера, то вы должны изменить учетную запись, под которой выполняется служба журналов и оповещений производительности, на соответствующую доменную учетную запись, которая имеет локальные администраторские права на компьютере, за которым вы собираетесь удаленно наблюдать.
Вы можете сделать это из окна службы, где вы должны изменить учетную запись службы на доменную учетную запись. В большинстве случаев лучше использовать ту же доменную учетную запись, которую вы используете для службы SQLсервера.
Как и многие другие администраторы баз данных, вы, вероятно, часто следите за своими SQLсерверами со своего настольного компьютера с помощью системного монитора. Если вы недавно перешли с Windows 2000 Workstation на Windows XP Workstation, то у вас могут возникнуть проблемы с использованием системного монитора для удаленного мониторинга SQLсервера, если вы храните файлы журналов в формате .blg (двоичный журнал производительности). Проблема заключается в том, что формат .blg файлов изменился после выхода XP.
Например, если вы используете Windows XP для ведения журнала счетчиков, используя системный монитор с SQLсервера, установленного на машине с Windows 2000, а затем пытаетесь открыть этот файл на неXP компьютере, то у вас это не получится изза различий в формате файла. Вы можете открыть этот файл на своей машине с XP или использовать утилиту relog.exe для преобразования .blgфайла в форматы .tsv или .csv.
Начиная с Windows 2003, стало возможным управлять монитором производительности через командную строку. Описание консольной утилиты Logman см. здесь http://technet2.microsoft.com/windowsserver/en/library/25d92f21ffad45c7824eb8c291559ebd1033.mspx?mfr=true.
Случай искаженных результатов
Даже если ваш код безошибочно проходит все стандартные тесты, в реальных условиях эксплуатирования ошибки могут возникнуть, например, когда несколько процессов одновременно обращаются к базе данных непредсказуемым образом. Конечно же, мы должны не допустить этого, ведь уже сегодня существуют средства эмулирования параллелизма во время тестирования.
Параллелизм в базах данных может становиться причиной коварных, трудно объяснимых и сложно воспроизводимых ошибок. Например: что случится, когда несколько процессов одновременно выполняют чтение и запись базы данных непредсказуемым образом? Будут ли ваши отчеты абсолютно верны? Не обязательно.
Верите вы или нет, но при параллельном изменении данных и выполнении статистических запросов к этим же данным, периодически ваши статистические данные могут быть немного ошибочными. Этот феномен может оставаться незамеченным некоторое время, и даже после его обнаружения такие ошибки сложно воспроизвести.
На самом деле подобные ошибки невозможно воспроизвести без симуляции параллельного выполнения. Эта проблема возникает в реальных условиях очень часто. В данной статье я воспроизведу этот феномен и продемонстрирую, как точность информации, возвращенной из оператора SELECT, может зависеть от уровня изоляции.
Растите вместе с SQL Server 2005 /
SQL Server 2008 —
NUMA
Эта статья посвящена технологии
NUMA (Non Uniform Memory Access
— архитектура неоднородного доступа к памяти) — функции, доступной
в SQL Server. NUMA — очень
полезное средство для увеличения масштаба вашего сервера.
Еще до обсуждения вопроса, как SQL Server 2005 поддерживает NUMA, мы должны рассмотреть несколько вопросов. Например, один из часто задаваемых вопросов: в чем разница между вертикальным и горизонтальным масштабированием?
Вертикальное масштабирование предполагает увеличение производительности сервера путем увеличения количества процессоров, увеличения дискового пространства или добавления памяти. Горизонтальное масштабирование достигается распределением загрузки среди нескольких относительно недорогих серверов. SQL Server 2005/2008 поддерживает как вертикальное, так и горизонтальное масштабирование.
Еще один часто встречающийся вопрос — это что лучше: вертикальное или горизонтальное масштабирование? Я бы сказал, что это очень зависит от ситуации и предъявляемых требований.
Давайте разберемся, что же такое NUMA и как он помогает в вертикальном масштабировании сервера.
NUMA — это аббревиатура от NON UNIFORM MEMORY ACCESS (неоднородный доступ к памяти). Современные компьютеры содержат очень мощные ЦП, которые могут работать быстрее, чем оперативная память, установленная в этих компьютерах. Это означает, что каждый раз при обновлении ЦП нам нужно обеспечить максимальную производительность сервера, так как доступ к памяти ограничен или работает медленно, а процессоры работают настолько быстро, что начинают страдать от недостатка работы. Современные операционные системы способны выжать нужную производительность из процессора, но те ограничены возможностями памяти по скорости передачи данных. NUMA пытается решить эту проблему, предоставляя независимые области памяти для каждого процессора, что снижает вероятность обращения разных процессоров к одной области памяти, приводящей к потере производительности.
В NUMA каждая группа процессоров имеет свою собственную память и, возможно, свои каналы ввода/вывода (см. рис. 1). Однако каждый процессор может получить упорядоченный доступ к памяти, принадлежащей другой группе. Каждая группа называется узлом NUMA. Количество процессоров в одном узле NUMA зависит от производителя оборудования. Доступ к локальной памяти быстрее, чем доступ к памяти, ассоциированной с другими узлами NUMA. Отсюда и возникло название: архитектура неоднородного доступа к памяти.
В оборудовании NUMA области памяти могут находиться на разных физических шинах. Т. к. NUMA использует локальную и внешнюю память, доступ к одним областям памяти может выполняться медленнее, чем к другим. Термины локальная (local) и внешняя (foreign) память обычно используются по отношению к текущему выполняющемуся потоку (thread). Локальная память — это память, находящаяся в том же узле, что и процессор, выполняющий этот поток. Любая память, не принадлежащая узлу, на котором выполняется поток, является внешней. Внешнюю память называют также удаленной (remote). Соотношение стоимости доступа к внешней памяти к стоимости доступа к локальной памяти называется NUMAкоэффициентом. Главным преимуществом архитектуры NUMA является масштабируемость. Архитектура NUMA была разработана для преодоления ограничений масштабируемости архитектуры SMP.
Сценарии использования архитектуры NUMA
Нет соответствия портов и NUMA
Это стандартное состояние на компьютере с NUMAоборудованием и единственным экземпляром SQL Server 2005. Весь трафик поступает через один порт и циклически распределяется между всеми доступными узлами NUMA. NUMA улучшает локальность памяти и доступ к ЦП, увеличивает количество потоков, обеспечивающих операции ввода/вывода и отложенной записи. В момент установки соединения, рабочий процесс SQL Server оказываеся привязан к определенному NUMAузлу. Это обеспечивает балансировку нагрузки между узлами NUMA. Клиентские приложения могут подсоединяться к одному порту, что упрощает развертывание (см. рис. 2).
Ассоциирование одного порта с несколькими узлами для увеличения производительности приоритетного приложения
Привязывание одного порта к нескольким аппаратным NUMAузлам для обслуживания наиболее приоритетного приложения. Память и ресурсы ЦП двух приложений зафиксированы, предоставляя основному приложению троекратное количество памяти и ресурсов ЦП относительно второстепенного приложения. Второстепенное приложение может быть вторым экземпляром SQL Server, менее важной функцией в том же экземпляре SQL Server или даже исполняться в рамках той же самой БД. Таким образом, можно обеспечить некую форму приоритетного выполнения потока с помощью предоставления привилегированному соединению дополнительных ресурсов (см. рис. 3).
Ассоциирование нескольких портов с несколькими узлами
Несколько портов может быть сопоставлено с одними и теми же узлами NUMA. Это позволяет вам назначать различные разрешения на разные порты. Например, вы можете жестко ограничить доступ, предоставляемый через порт с помощью управления правами доступа на соответствующей конечной точке TCP. В этом примере, порт 1450 широко доступен из локальной сети. Порт 1433 открыт в Интернет через брандмауэр, но доступ жестко ограничен. Оба порта в равной степени используют все преимущества NUMA (см. рис. 4).
Аппаратная и программная реализации архитектуры NUMA
Этот раздел поможет вам понять особенности аппаратной и программной реализации NUMA. Серверы с аппаратной поддержкой NUMA имеют несколько системных шин, каждая из которых обслуживает небольшую группу процессоров, каждая группа процессоров обладает своей собственной памятью и своим каналом ввода/вывода. Каждый процессор имеет возможность упорядоченного доступа к памяти других групп. Каждая группа называется узлом NUMA. Производитель оборудования должен указать вам количество процессоров, поддерживаемых в одном узле NUMA. Аппаратная архитектура NUMA может быть настроена для использования памяти с чередованием адресов (inteleave), вместо использования программной реализации NUMA. В этом случае Windows, а значит и SQL Server, не обнаружит аппаратной поддержки NUMA. Вы можете выполнить следующий запрос, чтобы узнать количество узлов памяти доступных SQL Server.
SELECT DISTINCT memory_node_id
FROM sys.dm_os_memory_clerks
SYS.DM_OS_MEMORY_CLERKS — это динамическое административное представление (DMV). Подробную информацию о нем ищите по адресу http://msdn.microsoft.com/ruru/library/ms175019.aspx.
Если SQL Server возвращает только один узел памяти (узел 0), компьютер либо не имеет аппаратной поддержки NUMA, либо аппаратное обеспечение настроено на использование чередующейся памяти (не NUMA). Если вы считаете, что аппаратная поддержка NUMA настроена неправильно, обратитесь к поставщику аппаратных средств, чтобы он включил поддержку NUMA. SQL Server не обрабатывает конфигурацию NUMA, если в режиме аппаратной NUMA в системе имеется не более четырех ЦП и по крайней мере на одном узле находится только один ЦП.
SQL Server 2005 позволяет группировать процессоры в узлы, называемые программными NUMA. Как правило, программный NUMA конфигурируется, когда имеется несколько ЦП, но нет аппаратной поддержки NUMA, но вы также можете использовать программные NUMA для дальнейшего разделения аппаратных NUMAузлов на более мелкие группы. Только планировщик SQL Server и сетевой интерфейс SQL Server (SNI) поддерживают программный NUMA. Следовательно, программный NUMA не влияет на узлы памяти, созданные на основе аппаратной поддержки NUMA. Поэтому, например, если в компьютере с поддержкой SMP установлено 8 ЦП, при создании четырех программных NUMAузлов по два ЦП в каждом, все четыре NUMAузла будут обслуживаться лишь одним узлом памяти. Программный NUMA не обеспечивает соответствия памяти и ЦП. К преимуществам программного NUMA относятся уменьшение количества узких мест операций вводавывода и отложенной записи на компьютерах с большим количеством ЦП и без аппаратной поддержки NUMA. Для каждого NUMAузла существует один поток вводавывода и один поток отложенной записи. В зависимости от использования базы данных, эти единичные потоки могут создавать узкие места по производительности. Настройка четырех программных NUMAузлов дает четыре потока вводавывода и отложенной записи, что может повысить производительность.
Нельзя создать программную конфигурацию NUMA, в которую включены процессоры, принадлежащие разным аппаратным NUMAузлам. Например, если на компьютере установлено 8 ЦП (0...7) и имеется два аппаратных NUMAузла (03 и 47), можно создать программную NUMAконфигурацию, объединив ЦП (0,1) и ЦП (2,3). Нельзя создать программную NUMAконфигурацию с участием ЦП (1,5), но можно использовать соответствие ЦП, чтобы установить соответствие экземпляра SQL Server с процессорами из различных NUMAузлов. Для предыдущего примера это означает, что если SQL Server использует ЦП 03, для них будет существовать один поток вводавывода и отложенной записи. Если в предыдущем примере SQL Server использует ЦП 1, 2, 5 и 6, он получит доступ к двум NUMAузлам и, соответственно, двум потокам вводавывода и отложенной записи.
Как SQL устанавливает соответствие между программными и аппаратными узлами NUMA
Узлы с программной архитектурой NUMA определяются один раз для всех экземпляров SQL Server 2005, содержащихся на компьютере, таким образом, все экземпляры компонента Database Engine будут видеть одни и те же узлы с программным NUMA. Затем каждый экземпляр компонента Database Engine использует параметр affinity mask (маска ассоциации), чтобы выбрать нужные процессоры. Каждый экземпляр будет использовать любой узел с программной архитектурой NUMA, который связан с этими процессорами.
При запуске Windows распределяет память для операционной системы из аппаратного узла NODE 0. Соответственно узел NODE 0 будет иметь меньше локальной памяти, доступной для приложений, чем другие узлы. Данная проблема усложняется, если имеется большой системный файловый кэш. Если SQL Server запускается на компьютере с несколькими узлами NUMA, он попытается запуститься на узле NUMA, отличающемся от узла NODE 0, чтобы его глобальные структуры могли быть размещены в локальной памяти.
Как назначить соединения для узлов NUMA
Соединения по протоколам TCP и VIA могут быть привязаны к одному или нескольким определенным узлам NUMA. Если соединения не привязаны или подключаются через именованные каналы или общую память, они распределяются по узлам NUMA циклически. В пределах узла NUMA соединение выполняется на наименее загруженном планировщике данного узла. Изза циклического характера назначения новых соединений может случиться так, что все ЦП узла будут заняты, в то время как другой узел будет свободен. Если количество ЦП очень мало (например, два) и наблюдается большой дисбаланс планирования изза долго выполняющихся пакетов, например массовой загрузки, возможно, будет получен прирост производительности при отключении NUMA.
Как настроить NUMA на SQL Server 2005 / 2008
Крайне рекомендуется выполнить резервное копирование вашей системы до конфигурирования. Обратитесь, пожалуйста, по следующим ссылкам: http://msdn2.microsoft.com/enus/library/ms345357.aspx, http://msdn2.microsoft.com/enus/library/ms345346.aspx.
Новое в SQL Server 2008
В состав SQL Server 2008 включены два очень интересных DMV.
dm_os_memory_nodes
Для выполнения этого DMV вам понадобится разрешение VIEW SERVER STATE. Для выделения внутренней для SQL Server памяти используется SQL Server Memory Manager. Отследив разницу между счетчиками памяти процессов и внутренними счетчиками, можно определить объем памяти в пространстве памяти SQL Server, используемой внешними компонентами. Узлы создаются на основе физических узлов NUMA. Они могут отличаться от процессорных узлов из sys.dm_os_nodes. Распределение памяти, выполняемое непосредственно Windows не отслеживается, отслеживается только распределение памяти, выполненное SQL Server. Подробная информация содержится в табл. 1.
dm_os_nodes
Для выполнения этого DMV вам понадобится разрешение VIEW SERVER STATE. Внутренний компонент SQL OS, недоступный снаружи, создает структуры узлов, имитирующие расположение процессоров. Эти структуры могут быть изменены с помощью программной архитектуры NUMA, для создания пользовательского комплектования узлов. Структура dm_os_nodes описана в табл. 2.
Табл. 1
Имя колонки |
Тип данных |
Описание |
memory_node_id |
smallint |
Идентификатор узла памяти. Связан со значением memory_node_id представления sys.dm_os_memory_clerks |
virtual_address_space_reserved_kb |
bigint |
Объем зарезервированного виртуального адресного пространства (в КБ), которое ни зафиксировано, ни сопоставлено с физическими страницами |
virtual_address_space_committed_kb |
bigint |
Объем виртуального адресного пространства (в КБ), зафиксированного или сопоставленного с физическими страницами |
locked_page_allocations_kb |
bigint |
Объем физической памяти (в КБ), заблокированной SQL Server |
single_pages_kb |
bigint |
Объем зафиксированной памяти (в КБ), выделенной с
помощью механизма распределения одиночных страниц узла памяти. Эта
память распределяется из буферного пула. Данное значение указывает на
узел, от которого исходит запрос на выделение памяти, |
multi_pages_kb |
bigint |
Объем зафиксированной памяти (в КБ), выделенной с помощью механизма многостраничного распределения потоков этого узла. Указанная память выделяется из пространства, находящегося вне буферного пула. Данное значение указывает на узел, от которого исходит запрос на выделение памяти, а не на физическое положение выделенной памяти |
shared_memory_reserved_kb |
bigint |
Объем общей памяти (в КБ), зарезервированной данным узлом |
shared_memory_committed_kb |
bigint |
Объем общей памяти (в КБ), зафиксированной данным узлом |
Табл. 2
Имя колонки |
Тип данных |
Описание |
node_id |
smallint |
Идентификатор узла |
node_state_desc |
Nvarchar(256) |
Описание состояния узла. Сначала отображаются взаимоисключающие значения, затем все их комбинации. Например: Оперативный, Недостаток ресурсов потоков, Отложенный с вытеснением Существует четыре взаимоисключающих значения параметра node_state_desc: Online: Узел в оперативном режиме Offline: Узел в автономном режиме Idle: Узел не имеет ожидающих выполнения запросов и находится в состоянии бездействия Ready for Idle: Узел не имеет ожидающих обработки запросов и готов к переходу в состояние бездействия. Существует три комбинации значения параметра node_state_desc: DAC: Данный узел зарезервирован для выделенного административного соединения (dedicated administrative connection). Thread Resources Low: Недостаточно памяти на этом узле для создания новых потоков. Hot Added: Указывает, что узлы были добавлены в ответ на событие «горячей» замены ЦП |
memory_object_address |
varbinary(8) |
Адрес объекта памяти, связанного с данным узлом. Связь «один к одному» для представления sys.dm_os_memory_objects. memory_object_address |
memory_clerk_address |
varbinary(8) |
Адрес клерка памяти, связанного с данным узлом. Отношение «один к одному» для представления sys.dm_os_memory_clerks memory_clerk_address |
io_completion_worker_address |
varbinary(8) |
Адрес исполнителя, связанного с завершением сеанса вводавывода для данного узла. Отношение «один к одному» для представления sys.dm_os_workers. worker_address |
memory_node_id |
smallint |
Идентификатор узла памяти, к которому принадлежит данный узел. Отношение «многие к одному» для представления sys.dm_os_memory_nodes. memory_node_i |
cpu_affinity_mask |
bigint |
Битовая карта, идентифицирующая ЦП, с которыми связан данный узел |
online_scheduler_count |
smallint |
Количество оперативных планировщиков, управляемых данным узлом |
idle_scheduler_count |
smallint |
Количество оперативных планировщиков, не имеющих активных исполнителей |
active_worker_count |
int |
Количество исполнителей, активных на всех планировщиках, управляемых данным узлом |
avg_load_balance |
int |
Среднее количество задач, выполняемых одним планировщиком на данном узле |
timer_task_affinity_mask |
bigint |
Битовая карта, определяющая планировщиков, которым можно назначить временные задачи |
permanent_task_affinity_mask |
bigint |
Битовая карта, определяющая планировщиков, которым можно назначить постоянные задачи |
resource_monitor_state |
bit |
Каждому узлу соответствует отдельный монитор ресурсов. Монитор ресурсов может находиться в состоянии работы или бездействия. Значению 1 соответствует рабочее состояние, значение 0 означает бездействие |
Закрыть дыры в тестировании ваших баз данных
DOWNLOAD
Это первая из трех коротких статей о юнит-тестировании TSQL-кода. В следующей статье я более подробно опишу, как использовать C# и NUnit (инфраструктуру (framework) юнит-тестирования с открытым исходным кодом для .Net-языков) для получения результатов юнит-тестов из хранимых процедур. Третья статья описывает способы юнит-тестирования модификаций базы данных и также использует C# и NUnit.
Неправильные или неполные юниттесты баз данных могут выполняться успешно, но не выявлять всех проблем вашего приложения — они могут дать лишь ложное ощущение надежности. Следующие рекомендации помогут вам улучшить ваши юниттесты.
Закрываем дыры: тестирование хранимых процедур
DOWNLOAD
В предыдущей статье «Закрываем дыры в тестировании ваших баз данных» мы рассматривали тестирование баз данных в целом. В данной статье мы сконцентрируемся на юнит-тестировании баз данных. Юнит-тестирование становится общепринятой практикой среди C#-, C++- и Java-программистов, т. к. это очень важно для обеспечения качества программного продукта. В этой статье мы продемонстрируем простой способ тестирования хранимых процедур, которые возвращают наборы результатов, а в следующей статье обсудим несколько более сложных методов, используемых для тестирования модификации баз данных.
Закрываем дыры: стрессовое тестирование хранимых процедур. Часть 1
DOWNLOAD
Вы можете написать хранимую процедуру, которая замечательно проходит регрессивные тесты. Вы передадите ее специалистам по тестированию в полной уверенности, что она абсолютно безошибочна. И не мечтайте, без стрессового тестирования вы можете упустить множество неприятных ошибок. Я продолжаю свою серию статьей, демонстрирующей, как избежать этих коварных ошибок.