Тестирование производительности баз данных

Авторы: Мазин Анатолий Викторович
Либман Михаил Сергеевич

Источник: RSDN Magazine #2-2010
Опубликовано: 04.12.2010
Версия текста: 1.1
Введение
Предлагаемый метод организации тестирования
Получение ранее выполненных запросов в БД
Выполнение запросов и сбор статической информации
Обработка полученных результатов
Выводы
Список литературы

Введение

В рамках решения задачи повышения скорости выполнения запросов с подзапросами поиска данных, удовлетворяющих шаблону, необходимо сравнить скорость выполнения запросов с и без применения предложенного способа оптимизации [1]. Для этого использовался метод тестирования производительности, описанный в данной статье. Предлагаемый метод будет интересен многим администраторам баз данных (АБД).

Каждый АБД часто сталкивается с необходимостью проверки, как изменение в базе данных (БД) или среде ее функционирования скажется на ее производительности. Например, изменение критических параметров оптимизатора запросов, смена версии СУБД, замена сервера и т.д. Наиболее простым решением является тестирование задач вручную или использование готовых тестов, подобных TPC [2]. Первый метод не дает достоверных результатов, второй - выполняет набор запросов в соответствии с заданными шаблонами, которые могут быть очень далеки от действительно выполняемых в БД. Одним из решений данной проблемы является использование средства Oracle Application Testing [3], которое может применяться в БД, работающих под управлением СУБД одноименной компании. Данный продукт позволяет сделать запись действительной рабочей нагрузки БД и воспроизвести ее в тестовой среде. Но заявленная проблема не решается для СУБД, несовместимых с данным ПО. Ниже описан метод, позволяющий имитировать работу БД на основании ранее выполненных в ней запросов.

Предлагаемый метод организации тестирования

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

Получение ранее выполненных запросов в БД

После выполнения сам запрос и связанные с ним структуры (например, план выполнения) некоторое время находятся в памяти, выделенной СУБД. Следовательно, обратившись к данной области памяти, можно получить требуемую нам информацию, а именно – текст запроса. Например, в СУБД Oracle 10.2 есть системное динамическое представление V$SQLTEXT, содержащее текст операторов SQL, принадлежащих разделяемым курсорам в системной глобальной области (SGA) [4]. Обратившись к нему, можно получить требуемую информацию, т.е. выполняемые в БД запросы. В DB2 для этих же целей можно воспользоваться sysibmadm.snapdyn_sql, в MSSQL – sysprocesses и функцией fn_get_sql.

Рассмотрим более подробно процесс получения выполненных запросов в СУБД Oracle. Представление V$SQLTEXT включает следующие атрибуты: ADDRESS, HASH_VALUE – используемые для уникальной идентификации курсора в кэше; PIECE – порядковый номер фрагмента запроса; SQL_TEXT – фрагмент запроса. По той причине, что размер атрибута SQL_TEXT ограничен 64 байтами, не все выполненные запросы помещаются в указанный формат. В этом случае запрос разбивается на несколько частей (PIECE), и каждой из них присваивается свой порядковый номер – атрибут PIECE. При помощи адреса, хеш-идентификатора и идентификатора части запроса, выполняется слияние «кусков». Ниже приведен код программы на языке PL/SQL, осуществляющий данные действия. В переменной f_sql будут содержаться искомые запросы.

      DECLARE
   f_sql   VARCHAR (32767);
BEGINFOR h IN (SELECT hash_value, address, MAX (s.piece)
             FROM v$sqltext s
             WHERE s.piece < 511
             GROUPBY hash_value, address
             ORDERBY 1)
   LOOP
      f_sql   := NULL;

      FOR p
      IN (SELECT sql_text, piece
          FROM v$sqltext
          WHERE     hash_value = h.hash_value
                AND address = h.address
                AND piece < 511
          ORDERBY piece)
      LOOP
         f_sql   := f_sql || p.sql_text;
      END LOOP;

      DBMS_OUTPUT.put_line (f_sql);
   END LOOP;
END;

Введенное ограничение на количество частей запросов piece<511 вызвано тем, что максимальная длина строки в СУБД – 32767 символов, и при большем количестве они не помещаются в переменную f_sql. Использование других средств программирования снимает данное ограничение. Так как запросы вытесняют друг друга из памяти по мере выполнения, необходимо осуществлять обращение к представлению с некоторой периодичностью. Создав подобное задание и сохраняя результаты его работы, можно получить выполненные пользователем запросы за требуемый период. Если в БД запущен периодический сбор статистики средствами СУБД, такими как StatsPask или AWR [5], то для получения требуемых данных можно обратиться к представлению схемы SYS STATS$SQLTEXT (StatsPask) или DBA_HIST_SQLTEXT (AWR). При работе с последним вся требуемая информация хранится в поле SQL_TEXT типа CLOB. Это упрощает получение данных, т.к. нет необходимости выполнять слияние частей запроса.

Получив выполненные запросы за требуемый период, нужно отфильтровать необходимые. Для этого можно воспользоваться регулярными выражениями. Также отметим, что часть запросов не будут содержать переменные, указанные пользователем в явном виде. Вместо них могут присутствовать переменные связывания (:SYS_0). Следовательно, дальнейшее их выполнение в БД для проведения тестирования бессмысленно. В этом случае вместо связанных переменных можно указывать значения из отношения, по которому выполняется выборка в данном запросе, или отбросить подобные запросы. Можно также изменять значения переменных из запросов для увеличения количества тестовых наборов.

Перейдем к следующему этапу, а именно – этапу их выполнения и сбору статистики работы.

Выполнение запросов и сбор статической информации

Получив множество запросов, которые были ранее выполнены в БД, необходимо разделить их на несколько групп и одновременно выполнить в БД, тем самым моделируя многопользовательскую среду. Каждая группа запускается по несколько раз. Для анализа процесса выполнения предлагается использовать трассировку сессии, подобная функция присутствует практически во всех СУБД. Аналогично вышесказанному рассмотрим запуск и разбор результатов трассировки в СУБД Oracle [5]. Для этого перед выполнением запросов из групп в БД необходимо выполнить команду:

      ALTER SESSION SET EVENTS '10046 trace name context forever, level 1';

Уровень трассировки, задаваемый параметром level, можно изменять. Для решения поставленной задачи хватит первого уровня, в случае необходимости получения статистик по событиям ожидания можно воспользоваться восьмым уровнем. В результате выполнения данной команды на сервере БД формируется файл отчета. В нем хранится информация о ходе работы сессии, обо всех выполненных операторах (на различных стадиях выполнения), событиях ожидания, возникших в процессе работы сессии, и т.д. Данный файл плохо структурирован, но из него при помощи утилиты Tkprof, поставляемой с сервером СУБД, можно получить обработанный трассировочный файл. Это упростит автоматическую обработку результатов эксперимента. В анализе каждого из запросов, выполненных в БД и представленных в трассировочном файле, нет смысла из-за возможности получения большого количества информации, обработать которую будет очень сложно. В полученном файле нас будет интересовать часть, хранимая под заголовком: «OVERALL TOTALS FOR ALL NON-RECURSIVE STATEMENTS».

OVERALL TOTALS FOR ALL NON-RECURSIVE STATEMENTS

call

count

cpu

elapsed

disk

query

current

rows

Parse

1048

0.10

0.13

0

0

0

0

Execute

1048

0.31

0.27

0

0

0

0

Fetch

1047

185.93

190.46

8848

8011691

0

3736

total

3143

186.35

190.87

8848

8011691

0

3736

Здесь содержится информация о суммарном времени выполнения всех запросов, выполненных дисковых операциях, количестве считанных строк и т.д. Необходимо отметить, что в процессе трассировки имя трассировочного файла по умолчанию генерируется в зависимости от процесса ОС, в рамках которого происходит работа. Это усложняет идентификацию групп запросов для дальнейшего сравнения. С целью устранения данной проблемы для упорядочивания получаемых файлов и выполняемых наборов запросов при помощи команды: alter session set tracefile_identifier=name будем присваивать результирующему файлу имя, определяемое параметром «name». Это позволить провести обработку и анализ результатов эксперимента. Параметр name предлагается формировать из двух частей: идентификатора группы запроса и номера эксперимента с данной группой, например, name=a_2. Это позволит выделять при обработке результатов различные группы и эксперименты.

Разработав средства, позволяющие автоматически получать из исходных трассировочных файлов обработанные утилитой Tkprof, а также выполняющие чтение информации из них, выберем требуемые данные и сохраним. Методы запуска и обработка результатов трассировки в других СУБД будут подобными. Далее необходимо обработать полученные результаты экспериментов для фильтрации измерений с грубой погрешностью, для этого предлагается использовать метод, описанный в следующем разделе.

Обработка полученных результатов

По причине того, что измерение физической величины не может быть выполнено абсолютно точно, любое измерение дает приближенный результат, иначе говоря, содержит погрешность измерения [6]. С целью повышения достоверности полученных в результате эксперимента значений необходимо проводить по несколько опытов над каждой группой запросов. При этом надо быть уверенным в воспроизводимости эксперимента, т.е. в том, что все полученные в опытах значения являются результатом случайного рассеянья, а не результатом доминирующего действия какого-либо неконтролируемого и неуправляемого воздействия, которое может возникнуть при проведении опыта. Для исключения грубых погрешностей применяют аппарат проверки статистических гипотез.

При обработке уже имеющихся результатов наблюдений произвольно отбрасывать отдельные результаты не следует, так как это может привести к фиктивному повышению точности результата измерений [7]. Группа измерений (выборка) может содержать несколько грубых погрешностей, и их исключение производят последовательно, по одному. Существует множество методов отсеивания ошибочных результатов измерений такие как: критерий Ирвина; критерий вариационного размаха; критерий Диксона; критерии трех сигм, Райта; критерий Смирнова; критерий Шовене; критерий Романовского и др. [8]. По критерию Романовского, конкурирующая гипотеза о наличии грубых погрешностей в подозрительных результатах подтверждается, если выполняется неравенство: |x-X|>=t*S, где t – квантиль распределения Стьюдента при заданной доверительной вероятности с числом степеней свободы k=n-l (l - число подозрительных результатов наблюдений); x - подозрительный результат измерения; X - координата центра распределения; S – среднеквадратичное отклонение. Точечные оценки распределения X и S результатов наблюдений вычисляются без учета l подозрительных результатов наблюдений.

Выполним обработку результатов эксперимента следующим образом:

  1. Для каждого набора запросов из каждого эксперимента вычислим X и S;
  2. Проведем фильтрацию результатов с высоким уровнем погрешности при помощи критерия Романовского;
  3. Повторно определим для каждого набора запросов из каждого эксперимента X и S;

В качестве результатов наблюдений предлагается использовать время, затрачиваемое на выполнение запросов (строка total, столбец elapsed из обработанного трассировочного файла), и время, затрачиваемое ЦП при выполнении запросов (строка total, столбец cpu из обработанного трассировочного файла).

Координата центра распределения X определяется положением случайной величины на числовой оси и может быть найдена несколькими способами. Наиболее фундаментальным [9, 10] является определение центра по принципу симметрии, т. е. такой точки на оси, слева и справа от которой вероятности появления различных значений случайной величины одинаковы и равны 0,5. В условиях, когда отсутствуют сведения о законе и виде распределения за оценку центра X рекомендуется принимать медиану вариационного ряда оценок: среднее арифметическое; медиана наблюдений; среднее арифметическое 90%-ной выборки; срединный размах вариационного ряда; центр размаха.

Напомним, что каждый набор запросов был идентифицирован, и каждый эксперимент пронумерован. Следовательно, мы можем выбрать данные, соответствующие каждой группе запросов. Для каждой группы нужно отбросить результаты экспериментов с грубой погрешностью и вычислить X и S. Получив X для каждого эксперимента, можно сравнить результаты до изменения БД или ее окружения и после, на основании чего сделать выводы о целесообразности использования предлагаемых методов оптимизации производительности БД.

Выводы

В рамках данной работы была предложена методология проведения экспериментов в БД, позволяющая сравнить производительность выполнения запросов индивидуальных для данной БД до и после выполнения требуемых изменений. Для решения этой задачи предложены методы получения запросов, ранее выполненных в БД, регистрации времени и статистики их выполнения, обработки результатов измерений. Предложенный метод использован для апробации способов повышения производительности запросов с подзапросами поиска данных, удовлетворяющих шаблону, где зарекомендовал себя с лучшей стороны. Указанный метод будет интересен многим АБД и разработчикам, которым требуется провести сравнения работы БД в различных условиях. При этом отмечается, что данная методика не является универсальной и, что не все требуемые вопросы были рассмотрены. В качестве направлений дальнейших исследований можно выделить исследования, позволяющие более точно обеспечить моделирование многопользовательской работы БД.

Список литературы

  1. Либман М.С. Мазин А.В. Повышение точности оценки кардинальности SQL запросов с оператором Like // Вопросы радиоэлектроники. 2010. Выпуск 4. С. 155-167.
  2. Transaction Processing Performance Concil // TPC Benchmarks/ URL. http://www.tpc.org/default.asp (дата обращения 06.06.2010)
  3. Oracle // Oracle Real Application Testing URL. http://www.oracle.com (дата обращения 06.06.2010)
  4. Oracle® Database Reference 10g Release 2 (10.2) // Oracle Database 10g Documentation Library. URL. http://download.oracle.com (дата обращения 06.06.2010)
  5. Oracle® Database Performance Tuning Guide 10g Release 2 (10.2) // Oracle Database 10g Documentation Library. URL. http://download.oracle.com (дата обращения 06.06.2010)
  6. Фадеев М.А. Элементарная обработка результатов эксперимента. Нижний Новгород: Изд-во Нижегородского госуниверситета, 2002. 108 с.
  7. Бранд. З. Статические методы анализа наблюдений. М.: Мир, 1975. 312с.
  8. Хамханов К.М. Основы планирования эксперимента. Улан-Удэ: Изд-во ВСГТУ, 2001. 50 с.
  9. Брянский Л.Н., Дойников А.С. Краткий справочник метролога. М.: Изд-во стандартов, 1991. 79 с.
  10. Гмурман В.Е. Теория вероятностей и математическая статистика. М.: Высшая школа, 2001. 479 с.


Эта статья опубликована в журнале RSDN Magazine #2-2010. Информацию о журнале можно найти здесь