v$session_wait 相關

imlihj2007發表於2011-02-21

v$session_wait
SID: session標識
EVENT: session當前等待的事件,或者最後一次等待事件。
WAIT_TIME: session等待事件的時間(單位,百分之一秒)如果本列為0,說明session當前session還未有任何等待。
SEQ#: session等待事件將觸發其值自增長
P1, P2, P3: 等待事件中等待的詳細資料
P1TEXT, P2TEXT, P3TEXT: 解釋說明p1,p2,p3事件

附註:
1.State欄位有四種含義﹕
Waiting:SESSION正等待這個事件。
Waited unknown time:由於設定了timed_statistics值為false,導致不能得到時間資訊。表示發生了等待,但時間很短。
Wait short time:表示發生了等待,但由於時間非常短不超過一個時間單位,所以沒有記錄。
Waited knnow time:如果session等待然後得到了所需資源,那麼將從waiting進入本狀態

Wait_time值也有四種含義:
值>0:最後一次等待時間(單位:10ms),當前未在等待狀態。
值=0:session正在等待當前的事件。
值=-1:最後一次等待時間小於1個統計單位,當前未在等待狀態。
值=-2:時間統計狀態未置為可用,當前未在等待狀態。

3.Wait_time和Second_in_wait欄位值與state相關:
如果state值為Waiting,那麼wait_time值無用。Second_in_wait值是實際的等待時間(單位:秒)。
如果state值為Wait unknow time,那麼wait_time值和Second_in_wait值都無用。
如果state值為Wait short time,那麼wait_time值和Second_in_wait值都無用。
如果state值為Waiting known time,那麼wait_time值就是實際等待時間(單位:秒),Second_in_wait值無用

SELECT event,
sum(decode(wait_time, 0, 1, 0)) "Curr",
sum(decode(wait_time, 0, 0, 1)) "Prev",
count(*) "Total"
FROM v$session_wait
GROUP BY event
ORDER BY count(*);

事件等待與常規處理:
------------------------------------------
<1> db file scattered read DB 檔案分散讀取 (太多索引讀,全表掃描-----調整程式碼,將小表放入記憶體)
這種情況通常顯示與全表掃描相關的等待。當全表掃描被限制在記憶體時,它們很少會進入連續的緩衝區內,而是分散於整個緩衝儲存器中。如果這個數目很大,就表明該表找不到索引,或者只能找到有限的索引。儘管在特定條件下執行全表掃描可能比索引掃描更有效,但如果出現這種等待時,最好檢查一下這些全表掃描是否必要。因為全表掃描被置於LRU(Least Recently Used,最近最少適用)列表的冷端(cold end),所以應儘量儲存較小的表,以避免一次又一次地重複讀取它們。
==================================================
該類事件的p1text=file#,p1是file_id,p2是block_id,透過dba_extents即可確定出熱點物件(表或索引)
select owner, segment_name, segment_type
from dba_extents
where file_id = &file_id
and &block_id between block_id and block_id + &blocks - 1;

<2> db file sequential read DB 檔案順序讀取 (表連線順序不佳-----調整程式碼,特別是表連線)
這一事件通常顯示單個塊的讀取(如索引讀取)。這種等待的數目很多時,可能顯示錶的連線順序不佳,
或者不加選擇地進行索引。對於大量事務處理、調整良好的系統,這一數值大多是很正常的,但在某些情況下,
它可能暗示著系統中存在問題。你應當將這一等待統計量與Statspack 報告中的已知問題(如效率較低的SQL)聯絡起來。
檢查索引掃描,以保證每個掃描都是必要的,並檢查多表連線的連線順序。DB_CACHE_SIZE 也是這些等待出現頻率的決定因素
。有問題的雜湊區域(Hash-area)連線應當出現在PGA 記憶體中,但它們也會消耗大量記憶體,從而在順序讀取時導致大量等待。
它們也可能以直接路徑讀/寫等待的形式出現。
===================================================
該類事件的p1text=file#,p1是file_id,p2是block_id,透過dba_extents即可確定出熱點物件(表或索引)
select owner, segment_name, segment_type
from dba_extents
where file_id = &file_id
and &block_id between block_id and block_id + &blocks - 1;

<3> free buffer waits 釋放緩衝區等待 (增大DB_CACHE_SIZE,加速檢查點,調整程式碼)
這種等待表明系統正在等待記憶體中的緩衝,因為記憶體中已經沒有可用的緩衝空間了。如果所有SQL 都得到了調優,
這種等待可能表示你需要增大DB_BUFFER_CACHE。釋放緩衝區等待也可能表示不加選擇的SQL 導致資料溢位了帶有索引塊的緩衝儲存器,
沒有為等待系統處理的特定語句留有緩衝區。這種情況通常表示正在執行相當多數量的DML(插入/更新/刪除),
並且資料庫書寫器(DBWR)寫的速度不夠快,緩衝儲存器可能充滿了相同緩衝器的多個版本,從而導致效率非常低。
為了解決這個問題,可能需要考慮增加檢查點、利用更多的DBWR 程式,或者增加物理磁碟的數量。

<4> buffer busy waits 緩衝區忙等待 (BUFFER熱塊)
這是為了等待一個以非共享方式使用的緩衝區,或者正在被讀入緩衝儲存器的緩衝區。緩衝區忙等待不應大於1%。檢查緩衝等待統計部分(或V$WAITSTAT):
A、如果等待處於欄位頭部,應增加自由列表(freelist)的組數,或者增加pctused到pctfree之間的距離。
B、如果等待處於回退段(undo)頭部塊,可以透過增加回滾段(rollback segment)來解決緩衝區的問題;
C、如果等待處於回退段(undo)非頭部塊上,就需要降低驅動一致讀取的表中的資料密度,或者增大DB_CACHE_SIZE;
D、如果等待處於資料塊,可以將資料移到另一資料塊以避開這個"熱"資料塊、增加表中的自由列表或使用LMT表空間;
E、如果等待處於索引塊,應該重建索引、分割索引或使用反向鍵索引。
為了防止與資料塊相關的緩衝忙等待,也可以使用較小的塊:
在這種情況下,單個塊中的記錄就較少,所以這個塊就不是那麼"繁忙"。
在執行DML(插入/更新/刪除)時,Oracle DBWR就向塊中寫入資訊,
包括所有對塊狀態"感興趣"的使用者(感興趣的事務表,ITL)。為減少這一區域的等待,
可以增加initrans,這樣會在塊中建立空間,從而使你能夠使用多個ITL槽。你也可以增加該塊所在表中的pctfree(當根據指定的initrans 建立的槽數量不足時,這樣可以使ITL 資訊數量達到maxtrans 指定的數量)。

<6> enqueue
enqueue 是一種保護共享資源的鎖定機制。該鎖定機制保護共享資源,如記錄中的資料,以避免兩個人在同一時間更新同一資料。enqueue 包括一個排隊機制,即FIFO(先進先出)排隊機制。注意:Oracle 的latch 機制不是FIFO。Enqueue 等待通常指的是ST enqueue、HW enqueue、TX4 enqueue 和TM enqueue。
A、ST enqueue 用於空間管理和字典管理的表空間的分配。利用LMT,或者試圖對區域進行預分配,或者至少使下一個區域大於有問題的字典管理的表空間。
B、HW enqueue 與段的高水位標記一起使用;手動分配區域可以避免這一等待。
C、TX4 enqueue是最常見的enqueue 等待,通常是以下三個問題之一產生的結果:
第一個問題是唯一索引中的重複索引,需要執行提交(commit)/回滾(rollback)操作來釋放enqueue。
第二個問題是對同一點陣圖索引段的多次更新。因為單個點陣圖段可能包含多個行地址(rowid),所以當多個使用者試圖更新同一段時,你需要執行提交或回滾操作,以釋放enqueue。
第三個問題,也是最可能發生的問題是多個使用者同時更新同一個塊。如果沒有自由的ITL槽,就會發生塊級鎖定。透過增大initrans 和/或maxtrans以允許使用多個ITL槽,或者增大表上的pctfree 值,就可以很輕鬆地避免這種情況。
D、TM enqueue 在DML 期間產生,以避免對受影響的物件使用DDL。如果有外來關鍵字,一定要對它們進行索引,以避免這種常見的鎖定問題。
<7> log buffer space 日誌緩衝空間 (寫REDO慢-----增大log_buffer,redo log file放到快速磁碟上)
當日志緩衝(log buffer)寫入重做日誌(redo log)的速度比LGWR 的寫入速度慢,或者是當日志轉換(log switch)太慢時,就會發生這種等待。為解決這個問題,可以增大日誌檔案的大小,或者增加日誌緩衝器的大小,或者使用寫入速度更快的磁碟。甚至可以考慮使用固態磁碟,因為它們的速度很高。
<8> log file switch 日誌檔案轉換 (歸檔慢-----增加或者擴大重做日誌)
有兩種情況:
A、log file switch (archiving needed)
當日志切換的時候由於日誌組迴圈使用了一圈但日誌歸檔還沒有完成,通常是io有嚴重問題,可增大日誌檔案和增加日誌組,調整log_archive_max_processes
B、log file switch (checkpoint incomplete)
當日志切換的時候由於日誌組迴圈使用了一圈但將被使用的日誌組中的checkpoint還沒有完成造成,通常是io有嚴重問題,可增大日誌檔案和增加日誌組
<9> log file sync 日誌檔案同步 (提交太頻繁----批次提交)
當使用者commit的時候通知lgwr寫日誌但lwgr正忙,造成的可能原因是commit太頻繁或者lgwr一次寫日誌時間太長(可能是因為一次log io size 太大),可調整 _log_io_size,結合log_buffer,使得 (_log_io_size*db_block_size)*n = log_buffer,這樣可避免和增大log_buffer引起衝突;放置日誌檔案於高速磁碟上

<10> library cache pin
該事件通常是發生在先有會話在執行PL/SQL,VIEW,TYPES等object時,又有另外的會話執行重新編譯這些object,即先給物件加上了一個共享鎖,然後又給它加排它鎖,這樣在加排它鎖的會話上就會出現這個等待。P1,P2可與x$kglpn和x$kglob表相關
X$KGLOB (Kernel Generic Library Cache Manager Object)
X$KGLPN (Kernel Generic Library Cache Manager Object Pins)
-- 查詢X$KGLOB,可找到相關的object,其SQL語句如下
(即把V$SESSION_WAIT中的P1raw與X$KGLOB中的KGLHDADR相關連)
select kglnaown, kglnaobj
from X$KGLOB
where KGLHDADR =
(select p1raw from v$session_wait where event = 'library cache pin')
-- 查出引起該等待事件的阻塞者的sid
select sid
from x$kglpn, v$session
where KGLPNHDL in (select p1raw
from v$session_wait
where wait_time = 0
and event like 'library cache pin%')
and KGLPNMOD <> 0
and v$session.saddr = x$kglpn.kglpnuse

-- 查出阻塞者正執行的SQL語句
select sid, sql_text
from v$session, v$sqlarea
where v$session.sql_address = v$sqlarea.add

<11> library cache lock
該事件通常是由於執行多個DDL操作導致的,即在library cache object上新增一個排它鎖後,
又從另一個會話給它新增一個排它鎖,這樣在第二個會話就會生成等待。可透過到基表x$kgllk中查詢其對應的物件。
-- 查詢引起該等待事件的阻塞者的sid、會話使用者、鎖住的物件
select b.sid, a.user_name, a.kglnaobj
from x$kgllk a, v$session b
where a.kgllkhdl in (select p1raw
from v$session_wait
where wait_time = 0
and event = 'library cache lock')
and a.kgllkmod <> 0
and b.saddr = a.kgllkuseress
and sid = < 阻塞者的sid >

當然也可以直接從v$locked_objects中檢視,但沒有上面語句直觀根據sid可以到v$process中查出pid,
然後將其kill或者其它處理
這樣,就可找到"library cache pin"等待的根源,從而解決由此引起的效能問題


<5> latch free (等待LATCH FREE)
latch是一種低階排隊機制(它們被準確地稱為相互排斥機制),用於保護系統全域性區域(SGA)中共享記憶體結構。
latch 就像是一種快速地被獲取和釋放的記憶體鎖。latch 用於防止共享記憶體結構被多個使用者同時訪問。
如果latch 不可用,就會記錄latch 釋放失敗。大多數latch 問題都與以下操作相關:
不能使用邦定變數(庫快取latch)、
重複生成問題(重複分配latch)、
緩衝儲存器競爭問題(緩衝器儲存LRU 鏈),
以及緩衝儲存器中的"熱"塊(緩衝儲存器鏈)。
也有一些latch 等待與bug(程式錯誤)有關,如果懷疑是這種情況,可以檢查MetaLink 上的bug 報告。
該事件的熱點物件可透過以下語句查詢,
其中&2值是v$session_wait中的P1RAW,x$bh中的欄位Hladdr表示該block buffer在哪個cache buffer chain latch 上,
可以透過v$latch_children定位哪些segment是熱點塊。
===================================================
select a.hladdr, a.file#, a.dbablk, a.tch, a.obj, b.object_name
from x$bh a, dba_objects b
where (a.obj = b.object_id or a.obj = b.data_object_id)
and a.hladdr = &2
union
select hladdr, file#, dbablk, tch, obj, null
from x$bh
where obj in (select obj
from x$bh
where hladdr = &2
minus
select object_id
from dba_objects
minus
select data_object_id from dba_objects)
and hladdr = &2
order by 4;
====================================================
***Latch 問題及可能解決辦法
------------------------------
* Library Cache and Shared Pool (未繫結變數 繫結變數,調整shared_pool_size)
每當執行SQL或PL/SQL儲存過程,包,函式和觸發器時,這個Latch即被用到.Parse操作中此Latch也會被頻繁使用.
* Redo Copy (增大_LOG_SIMULTANEOUS_COPIES引數)
重做複製Latch用來從PGA向重做日誌緩衝區複製重做記錄.
* Redo Allocation (最小化REDO生成,避免不必要提交)
此Latch用來分配重做日誌緩衝區中的空間,可以用NOLOGGING來減緩競爭.
* Row Cache Objects (增大共享池)
資料字典競爭.過度parsing.
* Cache Buffers Chains (_DB_BLOCK_HASH_BUCKETS應增大或設為質數)
"過熱"資料塊造成了記憶體緩衝鏈Latch競爭.
* Cache Buffers Lru Chain (調整SQL,設定DB_BLOCK_LRU_LATCHES,或使用多個緩衝區池)
掃描全部記憶體緩衝區塊的LRU(最近最少使用)鏈時要用到記憶體緩衝區LRU鏈Latch.太小記憶體緩衝區、
過大的記憶體緩衝區吞吐量、過多的記憶體中進行的排序操作、DBWR速度跟不上工作負載等會引起此Latch競爭。

[@more@]

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/9879835/viewspace-1046292/,如需轉載,請註明出處,否則將追究法律責任。

相關文章