Рис. 6.1. В простых клиент-серверных конфигурациях сеансу соответствует один серверный процесс и, следовательно, один трассировочный файл
Клиент-серверные приложения
Даже в нынешний век сложных многозвенных архитектур многие программы выполняются в простом клиент-серверном режиме, в особенности пакетные задания. Выделяя компонент приложения для тестирования, вы наверняка не откажете себе в такой роскоши. В подобной конфигурации любой сеанс Oracle создает единственный трассировочный файл, содержащий данные только этого сеанса (см. рис. 6.1).
Отсутствие межплатформенного стандарта именования трассировочных файлов вызвало у нашей компании затруднения при создании переносимого инструмента для поиска таких файлов. Мы рассматривали вариант с пополняемой таблицей шаблонов имен (т. е. регулярных выражений), которую можно было бы исправлять по мере переноса Oracle на новые платформы и выхода новых версий. Но мы пришли к выводу, что при поддержании актуальности такой таблицы неизбежно возникало бы множество ошибок. В результате мы остановились на таком алгоритме:
1. По заданным идентификатору и порядковому номеру выбранного
сеанса (значения V$SESSION.SID и V$SESSION.SERIAL#) определить системный идентификатор (SPID) соответствующего серверного процесса. Этот идентификатор содержится в поле V$PROCESS.SPID, соответствующем выбранному сеансу, и может быть получен при помощи соединения, аналогичного приведенному в примере 6.3.
Найти, в каком каталоге располагаются файлы трассировки. Этот каталог определяется значением параметра USERDUMPDEST, если V$SESSION.TYPE='USER', или параметра BACKGROUNDDUMPDEST, если V$SESSION.TYPE='BACKGROUND'.
Отсортировать содержимое каталога по убыванию даты изменения файла (например, командой ls -lt в UNIX). Имейте в виду, что время изменения файла (атрибут mtime) обычно указывается с точностью до секунды. Поэтому, если несколько файлов были созданы в течение одной секунды, сравнение значений mtime не даст ответа на вопрос, какой из них был создан последним.
Для каждого файла из полученного списка, значение mtime которого превышает время начала сбора данных (можно задать и более точное условие, но сравнение времени изменения со временем начала сбора данных - это более консервативный подход):
Найти в файле последнююпреамбулу. В особенности это касается платформ Microsoft Windows, где ядро Oracle часто стремится повторно использовать трассировочные файлы, дописываяновые данные к уже существующим. (Поэтому в одном файле может быть несколько преамбул.)
Найти в преамбуле строку, содержащую подстроку «pid» (для Unix и OpenVMS) или «thread id» (для Windows). Преамбулу составляют все строки вплоть до той, которая начинается с подстроки «***».
Если число, следующее за подстрокой «pid» или «thread id», совпадает с идентификатором SPID выбранного сеанса, нужный файл найден, и поиск заканчивается.
Если в файлах из выбранного списка отсутствует подходящий идентификатор процесса, поиск также заканчивается: искомые файлы отсутствуют.
Для проекта Sparky, о котором можно прочитать на сайте http:// www.hotsos.com,мною был написан переносимый код на Perl, выполняющий действия, аналогичные описанным.
Такой метод просмотра содержимого файлов может показаться не очень элегантным, особенно если в данной организации используется только одна или две операционные системы. Однако достоинство приведенного алгоритма в его надежности для различных платформ и различных версий программного обеспечения Oracle. Алгоритм хорошо масштабируется в зависимости от количества файлов трассировки, находящихся в каталоге. Несколько хуже он масштабируется в случае, когда файлы трассировки имеют очень большие размеры и содержат по несколько преамбул.
Параллельное выполнение (Oracle PX)
При параллельном выполнении Oracle (Oracle Parallel eXecution - PX) серверный процесс Oracle порождает два или более дочерних процесса (называемых подчиненными процессами PX)для выполнения параллельного чтения и параллельной сортировки. Подчиненные процессы PX наследуют атрибуты трассировки от координатора запроса. Следовательно, включение расширенной трассировки SQL для сеанса, который использует функциональность PX, приведет к формированию нескольких файлов трассировки. Задача заключается в том, чтобы опознать и проанализировать всенужные файлы. Обычно она решается достаточно просто - необходимо оценить время изменения файлов трассировки, сформированных последними. Для запросов, использующих степень параллелизма p,количество nсоответствующих файлов трассировки будет находиться в диапазоне 1 < n < 2p+1 для каждого вовлеченного экземпляра.
Применение многопоточного сервера Oracle (MTS) несколько усложняет поиск данных трассировки. MTS делает возможным использование коммутируемых соединений, что приводит к созданию отношения «один-ко-многим» между сеансом и серверными процессами Oracle, которые обслуживают вызовы базы данных, выполненные сеансом (рис. 6.2). Соответственно, данные трассировки для одного сеанса могут оказаться разбросанным по двум или более трассировочным файлам. Ядро Oracle предоставляет полные сведения по идентификации сеанса и временные метки каждый раз, когда сеанс мигрирует в новый серверный процесс (а следовательно, и в новый файл трассировки). Создать логический эквивалент единого файла трассировки для конкретного сеанса несложно. Рассмотренный ранее способ поиска файлов трассировки претерпевает следующие изменения: