Включение и отключение трассировки SQL из стороннего сеанса также может привести к усечению данных трассировки, необходимых для определения природы рекурсивных отношений в SQL. Включение трассировки SQL после выполнения рекурсивных операций, но до завершения соответствующих родительских операций, приводит к отсутствию данных о потомках в файле трассировки. Например, если выполняется приведенный ниже код PL/SQL, то полученный файл трассировки будет отображать ряд рекурсивных отношений между различными элементами блока и самим блоком:
alter session set events '10046 trace name context forever, level 8'; declare
cursor lc is select count(*) from sys.source$; cnt number; begin
open lc;
fetch lc into cnt; close lc; open lc;
fetch lc into cnt; close lc;
end; /
Однако можно коренным образом изменить данные трассировки, убрав команду ALTER SESSION и включив трассировку из стороннего сеанса (например, при помощи DBMS_SUPPORT. START_TRACE_IN_SESSION) в ходе выполнения блока. Сделав так, вы обнаружите, что ядро опустит массу сведений для всех рекурсивных дочерних операций, выполнение которых началось прежде, чем была включена трассировка. Включение трассировки SQL из стороннего сеанса может привести к отсутствию в файле трассировки дочерних вызовов базы данных для всех рекурсивных родительских операций, перечисленных в файле трассировки.
Как и в рассмотренном ранее случае с отсутствием данных о вызовах базы данных при включении трассировки, лучшим лекарством от подобной ошибки сбора данных является ее предотвращение. Все должно получиться естественным образом, если сбор данных основывается на пользовательских действиях, как это и должно быть. Однако, даже если нажать кнопку «запуска трассировки» с небольшим опозданием, полученная ошибка сбора данных не так страшна, как описанная выше ошибка с прерыванием вызова базы данных. Несмотря на отсутствие деталей, способных пояснить вам, почему сеанс израсходовал именно столько времени, наличие данных о родительских вызовах базы данных обычно позволяет провести анализ.
Аналогично отключение трассировки SQL из стороннего сеанса означает возможность отсутствия в файле трассировки родительских вызовов базы данных для всех рекурсивных (dep > 0) операций, отмеченных в файле трассировки. Представьте себе, что в примере 6.11 трассировка уже была включена на момент начала приведенного фрагмента кода, а затем была выключена сторонним сеансом в момент, помеченный значком О. Результат такой трассировки показан в примере 6.12.
В примере 6.11 очевидно наличие рекурсивных отношений между вызовами базы данных, т. к. в нем присутствуют три операции со значением глубины dep=1 (они выделены жирным шрифтом в примерах 6.11 и 6.12). Проблема примера 6.12 в том, что трассировка была отключена прежде, чем ядро Oracle передало какие-либо сведения о рекурсивном родителе глубины dep=0 для наших операций. Обратите внимание на операцию глубины dep=0 в примере 6.11 (она также выделена жирным шрифтом), которая и служит родителем, но в примере 6.12 трассировка была завершена прежде, чем информация о родителе попала в файл трассировки.
Пример 6.12. В конце этого файла трассировки нет вызова базы данных, который бы следовал за событиями глубины dep=1, выступая как их родитель
Из усеченных данных примера 6.12 можно узнать о том, что присутствуют три рекурсивных операции SQL, для которых где-то существует родитель, но кто он - неизвестно. Такие вызовы базы данных остаются «сиротами». Отключение трассировки SQL из стороннего сеанса приводит к возможному отсутствию в файле трассировки родительских вызовов базы данных для всех рекурсивных (dep > 0) операций, упомянутых в этом файле
И вновь лучшее лекарство - это профилактика. Вы естественным образом избежите таких ошибок, если будете выбирать время остановки сбора данных, основываясь на наблюдениях за пользовательскими операциями, как это и должно быть.
< Предыдущая | Следующая > |
---|