DeepEdit!

Программирование баз данных на Oracle, техническая документация, литература, статьи и публикации

  • Увеличить размер шрифта
  • Размер шрифта по умолчанию
  • Уменьшить размер шрифта

Как программное обеспечение измеряет само себя

ак программное обеспечение измеряет само себя

Понять, каким образом ядро Oracle осуществляет измерение собствен­ных характеристик, не слишком сложно. Основой этого раздела по­служили наши исследования ядер Oracle8и Oracle9i, работающих в ОС Linux. Программное обеспечение Oracle в разных операционных системах может использовать разные системные вызовы. Для того чтобы разобраться с этим, необходимо с помощью программы, выпол­няющей трассировку системных вызовов определенного процесса, по­смотреть, что делает система Oracle. Например, Linux предоставляет для трассировки системных вызовов инструментальное средство strace. В других операционных системах такие программы называют­ся иначе: truss для ОС Sun Solaris (в действительности truss изна­чально был инструментом трассировки системных вызовов для Unix), sctrace для IBM AIX, tusc для HP-UX и st race для Windows. В дальней­шем я буду говорить о принятом в Linux  strace как о семействе инструентов трассировки системных вызовов.
Н а  момент написания этой книги инструментарий st race для различных операционных систем доступен по адресу http:// www.pugcentral.org/howto/truss.htm.
Программа strace проста в употреблении. Например, можно непосред­ственно наблюдать за деятельностью ядра Oracle, выполнив такую ко­манду:
В данном случае strace сообщает о том, что приложение Linux с иденти­фикатором процесса ID 12417 (в моей системе это процесс ядра Oracle) вызвала функцию чтения read и ожидает выполнения этого вызова (поэтому в выводе отсутствует правая скобка).
Чрезвычайно полезно просматривать вывод st race и вывод трассиров­ки Oracle SQL одновременно в двух окнах, чтобы видеть, когда строки появляются в обоих потоках вывода. Вызовы write, посредством кото­рых ядро Oracle передает данные трассировки, естественно, появляют­ся в выводе strace именно тогда, когда и ожидается. Благодаря присут­ствию этих вызовов легче понять, в какой момент действия ядра Oracle порождают данные трассировки. В Oracle9для Linux (и Oracle9для некоторых других операционных систем) сопоставить вывод strace и вывод трассировки SQL очень просто, т. к. значения, возвращаемые gettimeofday, сразу же появляются файле трассировки в качестве зна­чений tim. Применяя таким образом одновременно strace и трассиров­ку SQL, можно подтвердить или опровергнуть тот факт, что ваше ядро Oracle ведет себя так же, как приведенный в последующих разделах псевдокод.

Применение strace вызовет значительный эффект влияния из­мерителя (measurement intrusion effect) на производительность исследуемой программы. Этот эффект обсуждается ниже в дан­ной главе.
Фактическая продолжительность
Ядро Oracle получает все свои временные статистики с помощью вызо­вов операционной системы, в которой оно выполняется. В примере 7.1 показано, как программа, подобная ядру Oracle, вычисляет продолжи­тельность собственных действий.
Пример 7.1. Программа измеряет собственное время отклика
Функция gettimeofday - это системный вызов, имеющийся в POSIX-со-вместимых системах. Обратившись к документации на ОС, вы узнае­те, что gettimeofday возвращает вызывающей программе структуру данных языка C, содержащую количество секунд и микросекунд, про­шедших с начала эры Unix - 00:00:00 UTC 1 января 1970 года.

Обычно сведения о таких системных вызовах доступны в доку­ментации на ОС. Например, в Unix-системах для получения информации о gettimeofday можно ввести в командной строке man gettimeofday. Получить определение POSIX можно по адресу http://www.unix-systems.org/single_unix_specification/
Имейте в виду, что в своем псевдокоде я, чтобы не отвлекать вас, опустил ряд второстепенных деталей. Например, на самом деле функция gettimeofday возвращает не время, а 0 в случае успешного выполнения и -1 при неудаче. «Возвращаемое» время записывается в двухэлементную (составляющая секунд и со­ставляющая микросекунд) структуру по адресу, указанному первым аргументом вызова gettimeofday. Я считаю, что приведе­ние всех этих подробностей в псевдокоде лишь усложнило бы
описание.
Попробуем изобразить выполнение примера 7.1 на оси времени, как показано на рис. 7.2. На рисунке значение gettimeofday t0 = 1492 в мо­мент начала выполнения функции под названием do_something. В мо­мент окончания работы do_something значение gettimeofday t1 = 1498. Следовательно, измеренная длительность исполнения do_something -это = t1 - t0 = 6 тактов системных часов.

Чтобы упростить восприятие, я взял для времени значения в интервале 1492-1499. Конечно же, они не похожи на реаль­ные значения секунд и микросекунд, которые gettimeofday воз­вращает в двадцать первом веке. Можно считать, что это по­следние несколько разрядов реальных значений времени.
Ядро Oracle выводит две разновидности фактической продолжитель­ности: величина e отражает длительность отдельного вызова базы дан­ных, а величина ela - протяженность последовательности инструк­ций, исполняемой процессом ядра Oracle и снабженной измерительными средствами (часто это системный вызов). Ядро выполняет такие вычисления, исполняя код, организованный приблизительно так же, как псевдокод в примере 7.2. Обратите внимание, что ядро задейству-
Загрузка процессора
Ядро Oracle выводит не только фактическую продолжительность e для каждого вызова базы данных и ela для каждого системного вызова, но и общий объем процессорного времени, израсходованного каждым вызовом базы данных. В контексте диаграммы состояний и переходов, представленной на рис. 7.1, величина c может быть определена как приблизительное количество времени, в течение которого процесс на­ходился в одном из двух режимов:
пользовательском привилегированном
В POSIX-совместимых системах ядро Oracle получает информацию об использовании процессора от функции getrusage (как, например, в ОС Linux и многих других) или от аналогичной функции times в HP-UX и некоторых других ОС. Несмотря на то, что спецификации этих двух системных вызовов значительно отличаются друг от друга, я буду упо­треблять имя getrusage, подразумевая при этом обе функции. Каждая функция предоставляет вызывающей программе разнообразную ста­тистику процесса, включая структуры данных, содержащие следую­щие четыре характеристики:
Приблизительное время, проведенное процессом в пользователь­ском режиме.
Приблизительное время, проведенное процессом в привилегирован­ном режиме.
Приблизительное время, проведенное потомками процесса в поль­зовательском режиме.

•   Приблизительное время, проведенное потомками процесса в приви­легированном режиме.
Каждая из этих величин выражается в микросекундах независимо от точности полученных данных.
Скоро вы узнаете, что, хотя стандарт POSIX и предписывает функции getrusage возвращать результат в микросекундах, точ­ность информации в нем редко превышает доли сантисекунд.
Ядро Oracle вычисляет c, e и ela, выполняя код, устроенный приблизи­тельно так же, как псевдокод, приведенный в примере 7.3. Обратите внимание, что этот пример основан на примере 7.2 - он включает в себя исполнение системного вызова getrusage и последующую обработку ре­зультатов. Аналогично вычислениям, производимым gettimeofday, ядро Oracle отмечает объем времени процессора, израсходованного процес­сом на момент начала вызова базы данных, а затем - на момент завер­шения вызова. Разность между этими двумя значениями (cO и c1)- это приблизительный объем процессорного времени, израсходованного вызовом базы данных. Чуть позже я расскажу о том, насколько при­близительна эта величина.
Пример 7.3. Псевдокод, показывающий, как ядро Oracle измеряет собственное время исполнения и использованное процессорное время

 









jAntivirus