Представление V$SESSION_WAIT для каждого события предлагает информацию самого низкого уровня. Как следует из его названия, оно построено на ожиданиях сеансового уровня. В отличие от других представлений, где отражены итоги, V$SESSION_WAIT отображает состояние ожидания на данный момент. Это реальный материал, если его раскрыть. Поскольку информация из V$SESSION_WAJT записана в реальном времени, при каждом выполнении запроса могут получаться разные результаты. Последовательное выполнение запроса V$SESSION_WAIT помогает выявить шаблоны в событиях и процессах, а также указать, кто использует данный ресурс и какие другие процессы ожидают его освобождения. Более важно, что это представление отображает добытую при погружении информацию для событий ожидания и связанных с ними ресурсов, поэтому можно с определенностью идентифицировать области, которые необходимо настраивать.
Например, если сеанс ожидает сканирования индекса, что обозначается как событие
db filesequentialread,
необходимо представить номер файла и номер блока данных, для которых имеет место ожидание. Это и есть тот адрес, из которого приложению нужно получить данные. Внимание, дальше пойдет важная информация! Определим важные столбцы в V$SESSION_WAIT:• SID Номер идентификатора сеанса.
Seq# Это число является внутренним порядковым номером для события ожидания, связанного с сеансом. Поле используется с целью определения числа ожиданий для данного события, которое задерживает сеанс.
Event Имя события. Вот несколько типичных событий: постановка в очередь, ожидания типа "буфер занят", "защелка (внутренняя блокировка) свободна", выборочное чтение файла БД, последовательное чтение файла БД и ожидание вроде "буфер свободен". Нужно искать повторяющиеся события, но при этом
не следует считать таковыми события типа PMON Timer, RDBMS timer и т. п.
• Р[1-3] Три этих столбца содержат подробную информацию, которая расскажет, что на самом деле представляет собой данное событие. Значения в этих столбцах являются логическими отношениями
(внешними ключами) для других V$. Именно в этом месте следует быть
особенно внимательным, потому что интерпретация содержащихся здесь значений может зависеть от события ожидания.
Например, для события ожидания db file scattered read (выборочное чтение файла БД), что подразумевает текущий процесс сканирования полной таблицы: в столбце Р1 содержится номер файла, в Р2 — номер блока, получения которого ожидает процесс, а в РЗ содержится число блоков, которое следует прочесть, начиная с блока, номер которого указан в Р2. Используя Р1 для запроса к VSFILESTAT или DBA DATA FILES, а Р2 - для QUERY DBA EXTENTS или SYS.UET$, можно определить тот объект, который ожидает сеанс. Если обнаружено несколько процессов, ожидающих один и тот же файл или файлы одной и
той же файловой системы, нужно разобраться с распределением ввода/вывода,
чтобы найти способ разрешения проблемы.
Предположим, что заданное событие - "защелка свободна". В таком случае Р2 будет номером защелки, который отсылает нас к V$LATCH. Сделайте запрос к V$LATCH и увидите, которая из защелок является проблемной. Полный список ожиданий и связанных с ними параметров можно найти в приложении А к справочному руководству по Oracle.
Замечание
В этом контексте запрос ввода/вывода приводит к вводу не одного, а нескольких блоков.
State Состояние данного события является очень важным индикатором, поскольку из берутся подробности для интерпретации следующих двух столбцов: wait_time и seconds_in_wait. Без полного понимания состояния хранящаяся в этих столбцах информация становится абсолютно бесполезной. Есть всего четыре возможных состояния, конечно, если не считать Техас (шутка основана на полной синонимии в английском (американском) языке слов "штат" и "состояние", которые обозначаются одним английским словом state. —
Прим. пер.).
WAITING В данный момент сеанс ожидает события.
WAITED UNKNOWN TIME Справедливо, если значение параметра TIMED_STATISTICS равно FALSE.
WAITED SHORT TIME Это значение указывает, что сеанс находится в ожидании незначительное время. Не стоит беспокоиться из-за таких событий, пока они не станут происходить слишком часто.
WAITED KNOWN TIME Только в тот момент, когда процесс
приобретает ресурс, которого он дожидался, значение столбца STATE
изменяется на WAITED KNOWN TIME.
Значение этого столбца зависит от значения STATE и
измеряется в секундах:
If STATE in ('WAITING', 'WAITED UNKNOWN TIME', ' WAITED SHORT TIME' ) then
WAITTIME = Irrelevant; END If;
If STATE = 'WAITED KNOWN TIME' then
WAIT_TIME = Actual wait time, in seconds; END If;
Поясним записанный выше текст. Если процесс находится в состоянии WAITED_SHORT_TIME, то ожидаемое событие не представляет проблемы, по крайней мере, до тех пор, пока оно не начинает повторяться снова и снова. Если к этому времени мы уже находились в состоянии WAITING, мы и в самом деле не можем знать, чему равно окончательное значение WAIT_TIME, следовательно, его значение нам не потребуется (взгляните на SECONDS IN WAIT). Если STATE равно WAITED_ UNKNOWN_TIME, то это связано с тем, что TIMED STATISTICS не был установлен в TRUE и поэтому не имеет значения.
Но если система перегружена и сеанс ждет сразу нескольких ресурсов, а теперь начинает ждать еще один ресурс, статус ожидаемого события снова примет значение WAITING, a WAITJITME = Irrelevant в соответствии с первым условием If. Чтобы добиться лучшего понимания вопроса, советуем перечитать последние две страницы еще раз.
• Значение этого столбца также зависит от значения
столбца STATE.
If STATE in ('WAITED UNKNOWN TIME', 'WAITED SHORT TIME', 'WAITED KNOWN TIME' ) then
SECONDS_IN_WAIT = Irrelevant; END If;
If STATE = 'WAITING' then
SECONDS_IN_WAIT = Actual Wait Time in seconds; END If;
Чтобы уловить разницу между и
таемся найти текущее значение параметра Если
процесс снова в состоянии это по-прежнему значит, что не установлен параметр TIMED_STATISTICS, т. е. он не играет роли. Если состояние процесса - WAITED_SHORT_TIME, то в
настоящий момент процесс не находится в состоянии ожидания, следо-
вательно, значение параметра SECONDS_IN_WAIT не важно. И, нако-
нец, если процесс находится в состоянии WAITED KNOWN TIME,
содержимое столбца SECONDS_IN_WAJT снова бессмысленно (вместо
этого смотрите так как в настоящий момент процесс ниче-
настоящий момент процесс не находится в состоянии ожидания, следо-
вательно, значение параметра SECONDS_IN_WAIT не важно. И, нако-
нец, если процесс находится в состоянии WAITED KNOWN TIME,
содержимое столбца SECONDS_IN_WAJT снова бессмысленно (вместо
этого смотрите так как в настоящий момент процесс ниче-
го не ожидает. Значения в этом столбце могут не повторяться при неоднократном повторении запросов.
Если значения повторяются, сеанс в течение длительного времени ожидает какого-то конкретного события. Несколько запросов к этому представлению дают информацию о продолжительности ожидания сеансом заданного
Приведенные ниже примеры кодов иллюстрируют методологию настройки производительности, базирующуюся на ожидаемых событиях.
Сначала мы запускаем следующий запрос для проверки некоторых общих с базе данных
использованием представления
бытий ожидания V$SYSTEM_EVENT:
SQL> select *
2. from V$SYSTEM_EVENT
3 where Event in ('buffer busy waits',...
4 'db file sequential read'-
5 'db file scattered read',
1 enqueue',
' free buffer waits' ,
8 ' latch free' ,
9 1 log file parallel write'
10 1 log file sync' );
10 1 log file sync' );
2
3
4 5 6 7
SE.Total_Waits, SE.Time_Waited, SE.Average_Wait from V$SESSI0H S, V$SESSI0fLEVENT SE
where S.Username is not null and SE.Sid = S.Sid
and =
and SE. Event not like '%SQL.Net%'
SID
|
USERNAME
|
EVENT
|
TOTAL_WAITS
|
TIME_WAITED
|
AVERAGEJJAIT
|
|
29
|
OLUSER14
|
latch free
|
108
|
206
|
1,90740741
|
|
29
|
OLUSER14
|
file open
|
16
|
1
|
,0625
|
|
29
|
OLUSER14
|
db file scattered
|
read
|
7241
|
36357
|
5,02099158
|
29
|
OLUSER14
|
db file sequential
|
read
|
1010122
|
4611646
|
4,56543467
|
29
|
OLUSER14
|
buffer busy waits
|
6509
|
2592
|
,398217852
|
|
32
|
ID2USER
|
latch free
|
49
|
•63
|
1,28571429
|
|
32
|
ID2USER
|
file open
|
9
|
1
|
,111111111
|
|
32
|
ID2USER
|
db file sequential
|
read
|
8755
|
10056
|
1,1486008
|
32
|
ID2USER
|
db file scattered
|
read
|
3
|
10
|
3.33333333
|
32
|
ID2USER
|
log file sync
|
72739
|
47177
|
,648579167
|
|
32
|
ID2USER
|
buffer busy waits
|
1
|
0
|
0
|
|
51
|
VENDOR1
|
latch free
|
214
|
338
|
1,57943925
|
|
51
|
VENDOR1
|
file open
|
20
|
1
|
,05
|
|
51
|
VENDOR1
|
db file scattered
|
read
|
57469
|
207155
|
3,60463902
|
51
|
VENDOR1
|
buffer busy waits
|
3091
|
1221
|
,395017794
|
|
51
|
VENDOR1
|
db file sequential
|
read
|
656434
|
245814
|
,37446872
|
16 rows selected.
SQL>
Чтобы найти текущие события ожидания, ассоциируемые с подключенными сеансами, используем следующий запрос. Это очень динамичная информация, необходимо много раз повторить запрос, чтобы понять, какие события являются наиболее ожидаемыми для данного сеанса.
SQL> select SW. Sid, S.Username. SW. Event, SW.Wait_.Time,
2 . SW.State, SW.Seconds_In_Wait SEC_IN_WAIT
3 from V$SESSI0N S, V$SESSION_WAIT SW
4 where S.Username is not null
and SW.Sid = S.Sid
and SW.Event not like '%SQL*Net%'
7 order by SW.Wait_Time Desc;
SID USERNAME EVENT WAIT TIME STATE SEC IN WAIT
29 OLUSER14 db file sequential read 12 WAITED KNOWN TIME 1
32 ID2USER db file scattered read О WAITING О
51 VENDOR1 log file sync 0 WAITING 0
3 rows selected.
SOL>
Сеанс 29 ожидает события
dbfil sequential read.
В нашем тестировании данное событие было отмечено несколько раз, В следующем запросе показана дополнительная информация, относящаяся к этому ожидаемому событию. Мы несколько ограничили этот запрос, чтобы показать только некоторые из сеансов, попавших в зону нашего интереса.SQL> select Sid, Event, Pltext, P1, P2text, P2, P3text, P3
2 from V$SESSION_WAIT
3 where Sid between 28 and 52
and Event not like '%SQL%'
and Event not like '%rdbms%';
SID EVENT P1TEXT P1 P2TEXT P2 РЗ.ТЕХТ P3
29 db file sequential read file* 67 block# 19718 blocks 1
32 db file scattered read file# 67 block# 17140 blocks 32
51 db file sequential read file# 63 block# 7556 blocks ' 1
3 rows selected.
SQL>
Это ключевой момент. Два сеанса обращаются к одному и тому же файлу данных, а, возможно, и к одному и тому же сегменту. Р1 явно указывает на этот факт. Один сеанс выполняет просмотр полной таблицы, в то время как другой проводит сканирование индекса. Пользуясь информацией из Р1 и Р2, довольно просто выяснить, что это за сегмент. И с помощью следующего запроса мы сделаем это.
SQL> select Owner, SegmentJIame, Segmentjype, Tablespace_Name
2 from DBA.EXTENTS
3 where File_Id = &FileId_In
4 and &BlockId_In between Blockjd and Blockjd + Bloks - 1;
Enter value for fieldjn: 67
old 3: where File_id = &Fileid_In
new 3: where File_id = 67
Enter value for blockid_in: 19718
old 4: and &Blockid_In between Block_Id and Block_Id + Blocks - 1
new 4: and 19718 between Block_Id and Block_Id + Blocks - 1
OWNER SEGMENT NAME SEGMENT TYPE TABLESPACE NAME
MARKET TABLE ITEM_MASTER
1 row selected. SQL>
Результат получен. Запросы, обращающиеся к таблице вызывают какие-то ожидания. Посмотрим, какие операторы SQL выполняются в настоящее время в сеансе 29.
Мы создали небольшую функцию для выборки из представления V$SQLTEXT текста SQL для этого сеанса. Вот код этой функции:
GetSQLtext.sql
Simple function to access address, hash_value and return
SQL statement (will fail if stmt size > 32 k)
CREATE OR REPLACE
FUNCTION GetSQLTxt (HashAddr_In IN V$SQLTEXT. Hash_Value%TYPE ,Addr_ln IN V$SQLTEXT.Address%TYPE)
RETURN VARCHAR2 IS
Temp_S01Txt varchar2(32767);
CURSOR SQLPiece_Cur IS
select Piece, Sql_Text from V$SQLTEXT
where Hash_Value = HashAddr_In and Address = Addr_In ' order by Piece;
BEGIN
FOR SQLPiece_Rec IN SQLPiece_Cur
LOOP
Temp_SQLTxt := Temp_SQLTxt || SQLPiece_Rec.Sql_Text; END LOOP;
RETURN Temp_SQLTxt; END GetSQLTxt; /
Ниже приводится простой запрос SQL, в котором записанная выше функция используется для получения текста запроса на SQL:
SQL> select Sid, GetSQLtxt(Sql_Hash_Value, Sql_Address)
2 from V$SESSI0N
3 where Sid = &Sid_In; Enter value for sid_in: 29
old 2: where S.d = &Sid_In new 2: where Sid = 29 SID GETSQLTXT(SQL_HASH_VALUE, SQL_ADDRESS)
29 select sum(decode(im.action_code,' A', 1,'I',2, 'P','1',0) * im.disc_amt), sum(im.last_amt), sum(decode(im.action_code,'A' ,1,'I',2,'P',1,0) * im.m isc_amt) - sum(im.last_amt) from items_detail_info id, item_master_in fo@INVP im where id.period_num in ('00','02','04') and id.item_flg = ' 1' and im.action_code in (' A',' I',' P' )and (im. suff_code_id О 0 or im.stat ■ us in ('R', 'S') or im.type in ('C', 'S'))
SQL>
Задача решена.
Итак, отталкиваясь от знания факта, что событие f/й
jil sequential read
вызывает какие-то ожидания, мы определили не только сеансы, вносящие свой вклад в эти ожидания, но и полный текст оператора SQL.< Предыдущая | Следующая > |
---|