В некоторых случаях отмеченная в файле трассировки длительность вызова базы данных превышает тот период времени, на который была включена трассировка. Такое явление наблюдается, когда время начала вызова базы данных (значение tim - e) меньше времени начала сбора данных, т. е. когда tim - e < t0. Мы несколько раз наблюдали подобные случаи, когда трассировка была включена сторонним сеансом в ходе длительного выполнения блока PL/SQL. (Отличие этого случая от только что рассмотренного заключается во включении трассировки именно в ходе долго выполняющегося блока PL/SQL, а не просто в ходе выполнения длительного вызова базы данных). Единственная часть файла трассировки, которая может пострадать от феномена избыточного времени, - это первые отмеченные в файле трассировки операции с определенной рекурсивной глубиной (значением поля dep).
Подобное явление не так просто заметить, если несколько тысяч строк WAIT (не содержащих полей tim) предшествуют строке первого вызова базы данных, содержащей это поле. В главе 5 вы узнали, как выполнить обратный отсчет времени, начиная со значения первого поля tim файла через значения всех полей ela и до достижения первой строки. Однако этот метод подвержен заметному накоплению систематической ошибки, как это было показано при описании отсчета времени в главе 5.
Гораздо более удачный способ вычисления «виртуального» значения tim для первой строки WAIT файла трассировки заключается в том, чтобы ввести функции преобразования, которые позволяют преобразовывать значения полей tim Oracle к значениям системного времени и обратно. Соотношение между величиной tim и системным временем можно установить, сделав следующие шаги:
2. Исследуйте полученные данные трассировки. Он будет содержать такие строки:
1. Выполните приведенные ниже команды в SQL*Plus для системы, соотношение времен для которой вы хотите установить:
3. По этой информации вы можете установить прямое соответствие указанного значения поля tim указанной временной метке. В приведенном примере обратите внимание на совпадение составляющих секунд и миллисекунд двух значений (выделено жирным шрифтом). В изучаемой нами системе отношение между значениями времени очень просто: каждое значение поля tim - это просто количество микросекунд, прошедших с момента начала эры UNIX (00:00:00 UTC - 1 января 1970). В примере 6.10 приведена программа, которая служит мне инструментом для преобразования значений tim в системное время и обратно.
Рассмотрим простой пример файла трассировки, начальные строки которого содержат данные о событиях, которые произошли до момента начала сбора данных:
Нелегко понять, что происходит, если не преобразовать значения времени к сопоставимому формату. Возьмем из примера 6.10 программу для преобразования значения tim в моей Linux-системе в более удобочитаемое значение абсолютного времени и увидим, что вызов исполнения завершился только через 2,025881 секунды после включения трассировки:
Но фактическая продолжительность вызова исполнения составляет 30 секунд (e=30000000). То есть часть продолжительности этого вызова базы данных относится к периоду, предшествующему временной метке, выведенной в начале файла трассировки. Я уже говорил, что эта временная метка не всегда соответствует тому моменту времени, в который на самом деле был установлен атрибут трассировки. Придется отдельно отслеживать время включения трассировки (назовем его t0). Это проще всего сделать, отметив время в поле tim при выполнении команды на включение трассировки SQL.
Итак, вы определили, что в файле трассировки учтено избыточное время, и следующая задача состоит в том, чтобы избавиться от него. На рис. 6.7 показано, как это сделать. Здесь трассировка SQL включается в момент t0, во время некоторого вызова разбора внутри долго выполняющегося блока PL/SQL. При этом часть продолжительности e вызова разбора относится к интересующему нас интервалу наблюдения, а другая его часть - к периоду времени, предшествующему t0. Лишнее время легко вычислить, т. к. значение t0 в единицах tim известно. Не вошедшее в период наблюдения время T можно вычислить так:
Если первые несколько строк, переданные в файл трассировки, не содержат значения tim, то можно вычислить значение t для начала файла, преобразовав начальное значение временной метки (в строке ***) в соответствующее значение tim, как было показано выше. Помните, что временная метка сопоставлена моменту завершения операции, которая следует за данной строкой в файле трассировки. Задача сводится к ситуации, уже рассмотренной на рис. 6.7, в которой вам известны t, e, t0 (фактически и все промежуточные значения ela в случае, если длительность одного из событий ожидания также включает в себя t0).
При завершении сеанса, для которого была включена расширенная трассировка SQL, в файле трассировки будет учтено все время около момента завершения сеанса. Так, если сеанс отключает собственную трассировку командой ALTER SESSION SET EVENTS, в файле трассировки учитывается все время сеанса, прошедшее до момента выполнения этой команды. Если же трассировка отключается сторонним сеансом, то это отключение произойдет, скорее всего, в ходе выполнения события ожидания или вызова базы данных сеанса. В таком случае некоторые нужные данные о сеансе могут отсутствовать в файле трассировки.
Например, трассировка указанного сеанса отключается в момент времени tim=1043788733690992. Однако в конце файла трассировки содержится лишь следующее:
Обратите внимание на выделенную часть завершающего значения в поле tim: файл трассировки содержит сведения о том, что произошло до момента времени ...23,690992 (в секундах) и фактически на 4 микросекунды позже, но нет записей о том, что происходило между моментами ...23,690992 и ...33,690992. Не учтено ровно 10 секунд.
На рис. 6.8. показано, как сложилась такая ситуация. Трассировка SQL была выключена в момент t1, в ходе выполнения события ожидания z. Но ядро Oracle передает в файл трассировки строку события ожидания только по завершении этого события. Трассировка была выключена раньше, чем завершилось событие ожидания, никаких данных о нем в файле трассировки нет. Часть длительности события ожидания относится к периоду времени после t1, но та его часть, которая произошла до t1, остается неучтенной.
Рис. 6.8. Если трассировка SQL выключается сторонним сеансом в момент времени t1, то трассировка может завершиться в ходе выполнения некоторого события. В этом случае время, затраченное на данное событие, не появится в файле трассировки, в результате чего часть времени будет утеряна
В данном случае вычислить пропущенное время просто, ведь значение t1 в единицах tim известно. Это делается по формуле:
Опять-таки проще всего отслеживать tx, пометив момент времени, когда выполняется команда на отключение трассировки SQL. При отключении трассировки необходимо определить имя события, которое не было завершено на момент tx. Из стороннего сеанса это можно узнать посредством такой команды SQL:
Разработанный Hotsos сборщик данных Sparky выполняет подобный запрос непосредственно перед командой на включение и выключение трассировки. Если запрос не возвращает имени события, то все пропущенное время T следует отнести к процессорному времени. Если же запрос возвращает имя события, то по крайней мере некоторая часть пропущенного времени соответствует событию, имя которого возвратил запрос. При этом, как видно на рис. 6.8, некоторая часть пропущенного времени все равно может быть израсходована процессором.
Возможно, некоторая часть пропущенного времени израсходована на выполнение инструкций ядра Oracle, для которых отсутствуют средства измерения (подробно мы поговорим об этом в главе 7).
Может быть, удастся приблизительно определить, какую часть времени T следует отнести на счет загрузки процессора, а какую - сопоставить событию ожидания. Однако наша практика показала, что в случае, если запрос V$SESSION_WAIT возвращает имя события, сопоставление всего значения T этому событию будет хорошим приближением.
Наличие строк WAIT в конце файла трассировки несколько усложняет вычисление пропущенного времени, т. к. приходится осуществить еще одну операцию по отсчету времени. В данном случае вам придется получить значение t, отсчитывая время вперед от значения последнего поля tim файла через значения полей ela.
< Предыдущая | Следующая > |
---|