DeepEdit!

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

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

Устранение ошибок сбора данных

Как говорилось в главе 3, первостепенную важность имеет сбор данных трассировки SQL точно для выбранной временной области. Включение и отключение трассировки SQL точно в нужный момент особенно важ­но в тех случаях, когда выполняется диагностика операций с неболь­шим временем отклика. Если трассировкой сеанса управляет сторон­ний сеанс, то непопадание в заданную временную область возможно как в начале, так и в конце файла трассировки. Оставшаяся часть гла­вы рассказывает о том, как и почему возникают ошибки сбора данных и как получить максимум информации из трассировочных данных.
Погрешность времени включения трассировки
Если сеанс сам включает собственную трассировку SQL, то в его файле трассировки вы в первую очередь обнаружите информацию о команде
ALTER SESSION SET EVENTS. Если же атрибут трассировки сеанса устанав­ливается другим сеансом (например, при помощи, DBMS_SYSTEM.SET_EV
или DBMS_SUPPORT.START_TRACE_IN_SESSION), то сказать, каким будет пер­вое событие, попавшее в файл трассировки, становится сложнее.
Пропуск событий ожидания при включении трассировки
Если трассировка включается во время события ожидания, имеющего место между вызовами базы данных, то в начале файла трассировки мо­гут отсутствовать некоторые данные. Рассмотрим последовательность действий, показанную на рис. 6.6. Я создал два сеанса SQL*Plus: один идентифицируется как 7.10583 (значения SID и SERIAL# для сеанса), а другой назван «вторым». Во втором сеансе я выполнил приведенный ниже блок PL/SQL, введя в ответ на приглашения значения 7 и 10583:
Выполнение этого блока включает трассировку для сеанса 7.10583 и выводит время включения - 12:31:11. Следовательно, я знаю, что этот момент времени и есть точка начала нужного мне интервала сбора данных.
В сеансе 7.10583 я подождал несколько секунд, затем выполнил про­стой запрос текущего времени системы. Результатом запроса было 12:31:47. Затем я завершил сеанс 7.10583. Файл трассировки этого се­анса приведен в примере 6.7. Обратите внимание, что в файле трасси­ровки отражены операции, выполненные между 12:31:47.330 и при­близительно 12:31:47.983 (я получил второе значение, выполнив от­счет времени), но он не содержит данных для периода приблизительно в 36 секунд между 12:31:11 и 12:31:47.330.
Я мог полностью контролировать сеанс 7.10583 на протяжении его су­ществования, поэтому знаю, что 36 секунд, отсутствующие в файле трассировки, относятся к событию ядра SQL*Net message from client. Од­нако если бы я этого не знал, у меня не было бы способа корректно под­считать неучтенное время. Поэтому программа сбора данных Sparky (http://www.hotsos.comвыполняет запрос к V$SESSION_WAIT при вклю­чении (и отключении) трассировки. Выполнив при включении трасси­ровки следующий запрос, я буду знать, какое событие не было завер­шено на момент включения (12:31:11):
select event from v$session_wait where sid=7 and state='WAITING'
Пропуск вызовов базы данных при включении трассировки
Более сложная проблема возникает в случае, если трассировка сеанса включается в ходе вызова базы данных. Например, я включил трасси­ровку для сеанса 8.1665 в процессе выполнения долгой выборки, в ре­зультате чего были сформированы данные трассировки, представлен­ные в примере 6.8. При внимательном изучении этот файл может вы­звать беспокойство. Из более чем 87 700 строк данных трассировки, которые здесь не показаны, тысячи сантисекунд относятся к событи­ям ожидания курсора #1 (сумма значений поля ela для строк WAIT #1). Однако первым в файле трассировки отображен вызов базы данных UN-MAP (он специально выделен в тексте примера). Обратите внимание, что его общая продолжительность составляет всего 3 сотых доли секунды (e=3). Имеются тысячи сантисекунд, потраченных на события ожида­ния, порожденные некоторым вызовом базы данных, но вызов, отве­чающий за это время, так и не появляется в файле трассировки!
И что еще хуже - непонятно, где тот запрос, который подсчитывает за­писи в DBASOURCE? Продолжительность запроса составила более 10 се­кунд (я сидел и смотрел, как он выполнялся), и вернул он всего одну строку, а единственная строка FETCH в файле трассировки сообщает о том, что запрос выполнился практически мгновенно и не вернул ни одной строки.
В примере 6.9 показаны те данные, которые мы ожидали, но не смогли увидеть в примере 6.8. Этот файл получен в результате запуска трасси­ровки перед разбором запроса. Обратите внимание, что вместо двух вызовов базы данных (UNMAP и FETCH в примере 6.8) здесь мы видим це­лых пять вызовов:
Вызов PARSE для запроса к DBA_SOURCE, который имел место до того, как была включена трассировка в первом примере, поэтому данная строка не была передана в первый файл трассировки.
Вызов EXEC для запроса, который также начался до того, как была включена трассировка в первом примере, из-за чего и эта строка не попала в первый файл трассировки.
Вызов FETCH, на который ушла большая часть времени отклика за­проса. В первом примере этот вызов начался раньше, чем была включена трассировка, поэтому соответствующая строка тоже отсутствует в примере 6.8.
Вызов UNMAP освобождает сегмент сортировки, используемый одним из рекурсивных представлений.
Последний вызов FETCH, удостоверяющий отсутствие данных, дос­тупных курсору. Как видите, данный вызов выборки не возвращает строк.
И наконец, обратите внимание, что включение трассировки до начала запроса награждает нас данными STAT для сеанса, что само по себе при­ятно.



Включение трассировки sql во время выполнения любого длительно­го вызова базы данных приводит к потере данных, вроде той, которую мы только что рассмотрели. Важно уметь распознать такую ошибку сбора данных. Ведь если попытаться диагностировать причину ухуд­шения производительности на основе данных с такой ошибкой, то можно попасть в бездонную яму, т. к. придется иметь дело с большими объемами избыточно учтенного времени.
Подобную ошибку можно выявить, обратив внимание на то, что сумма значений ela для последовательности событий ожидания (строки WAIT) значительно превышает границы общей продолжительности вызова базы данных (значение e), породившего эти события ожидания. В при­мере 6.8 об ошибке говорит тот факт, что более 87 700 строк WAIT #1 бы­ли переданы за гораздо больший интервал времени, чем отмеченная фактическая продолжительность (e=3 сантисекунды) вызова UNMAP #1, который следует непосредственно за этими строками.
Профилактика - единственное лекарство, которое я могу порекомен­довать от такого рода ошибок сбора данных. Избегайте включения трассировки SQL в процессе выполнения длительного вызова базы данных. Если полученный файл трассировки содержит такую ошиб­ку, то лучше всего повторить процедуру сбора данных заново.
Включая расширенную трассировку SQL из стороннего сеанса, приложите все усилия к тому, чтобы не сделать этого во время выполнения длительного вызова базы данных. Если все же не удается избежать такой ситуации, то, вероятно, наилучшим вы­ходом будет применение одного из приемов, описанных в главе 8.

 









jAntivirus