[Oracle10G新特性]_11.等待界面
?
??? 這一篇主要內容就是關于Oracle的等待, 本文列舉了各個關于Oracle內部記錄等待信息的視圖及其意義。不過這個問題不常遇到,暫時還沒有可以進行實際應用的可能。暫時先學習一下,等以后有需要再回來仔細研究一下。
?
----------------------------------------------------------
等待界面
?
10g 等待界面為還沒有被 ADDM 捕獲的即時性能問題提供了有價值的診斷數據
?
??? “數據庫太慢了!”
?
??? 這句話通常出自一位嚴格的用戶之口。如果您和我一樣,那么在您的 DBA 生涯中您肯定無數次聽到過這句話。
??? 那么,您又怎樣解決該問題呢?除了對用戶置之不理之外(這是我們大多數人都不敢奢望的想法),您可能要做的第一件事就是查看是否有任何會話在等待數據庫內部或外部的任何事件。
?
??? Oracle 提供了一個簡單但一流的機制來達到此目的:V$SESSION_WAIT 視圖。該視圖顯示了有助于您的診斷的各種信息,如一個會話正在等待或已經等待的事件,以及等待了多長時間和多少次。例如,如果會話在等待事件 "db file sequential read",列 P1 和 P2 將顯示會話正在等待的塊的 file_id 和 block_id。
?
??? 對于大多數等待事件而言,這個視圖足夠了,但它還不是一個強健的調整工具,之所以如此說,至少是因為以下兩個重要原因:
?
??? ● 該視圖是當前情況的一個快照。當等待不再存在時,會話先前出現的那些等待的歷史也將消失,從而使得事后診斷非常困難。V$SESSION_EVENT 提供了累積的但不是非常詳細的數據。
??? ● V$SESSION_WAIT 包含了只與等待事件相關的信息;要獲得所有其它的相關信息(如用戶 ID 和終端),您必須將它和 V$SESSION 視圖結合使用。
?
??? 在 Oracle 數據庫 10g 中,等待界面經過了徹底的重新設計,從而只需更少的 DBA 干預即可提供更多的信息。在本文中,我們將瀏覽這些新的特性,并了解它們如何幫助我們診斷性能問題。對于大多數性能問題,您可以從自動數據庫診斷管理器 (ADDM) 中獲得擴展分析,但對于還沒有被 ADDM 捕獲的即時問題,等待界面將提供有價值的診斷數據。
?
?
增強的會話等待
?
??? 第一個增強涉及到 V$SESSION_WAIT 本身。這一點通過示例可以很好地說明。
?
??? 假定您的用戶抱怨會話掛起了。您查明了該會話的 SID,并在 V$SESSION_WAIT 視圖中選中了該 SID 的記錄。輸出顯示如下。
?
SID????????????????????? : 269
SEQ#???????????????????? : 56
EVENT??????????????????? :enq:TX - row lock contention
P1TEXT?????????????????? :name|mode
P1?????????????????????? : 1415053318
P1RAW??????????????????? : 54580006
P2TEXT?????????????????? :usn<<16 | slot
P2?????????????????????? : 327681
P2RAW??????????????????? : 00050001
P3TEXT?????????????????? :sequence
P3?????????????????????? : 43
P3RAW??????????????????? :0000002B
WAIT_CLASS_ID??????????? : 4217450380
WAIT_CLASS#????????????? : 1
WAIT_CLASS?????????????? : Application
WAIT_TIME??????????????? : -2
SECONDS_IN_WAIT????????? : 0
STATE??????????????????? :WAITED UNKNOWN TIME
??? 注意以粗體顯示的列;在這些列中,WAIT_CLASS_ID、WAIT_CLASS# 和 WAIT_CLASS 是 10g 中新增的列。列 WAIT_CLASS 指示等待的類型,必須將其作為有效的等待事件解決或者作為空閑的等待事件退出。在上面的例子中,等待類顯示為 Application,這表示它是一個需要您注意的等待。
?
??? 該列突出顯示那些能夠證明與您的調整最相關的少數幾條記錄。例如,您可以使用如下查詢來獲取事件的等待會話。
?
select wait_class, event, sid, state, wait_time, seconds_in_wait
from v$session_wait
order by wait_class, event, sid
/
??? 下面是一個樣例輸出:
?
WAIT_CLASS? EVENT?????????????????????? SID STATE??????????????? WAIT_TIME SECONDS_IN_WAIT
----------? -------------------- ---------- ------------------- ---------- ---------------
Application enq:TX -?????????????????? 269 WAITING????????????????????? 0????????????? 73
row lock contention???????
Idle??????? Queue Monitor Wait????????? 270 WAITING????????????????????? 0????????????? 40
Idle??????? SQL*Net message from client 265 WAITING????????????????????? 0????????????? 73
Idle??????? jobq slave wait???????????? 259 WAITING????????????????????? 0??????????? 8485
Idle??????? pmon timer????????????????? 280 WAITING????????????????????? 0????????????? 73
Idle??????? rdbms ipc message?????????? 267 WAITING????????????????????? 0????????? 184770
Idle??????? wakeup time manager???????? 268 WAITING????????????????????? 0????????????? 40
Network???? SQL*Net message to client?? 272 WAITED SHORT TIME?????????? -1?????????????? 0
?
??? 在這,您可以看到幾個事件(如 Queue Monitor Wait 和 JobQueue Slave)被明確地歸為 Idle 事件。您可以將它們作為非阻塞等待消除掉;不過,有時這些“空閑”事件可能指示一個內在的問題。例如,與 SQL*Net 相關的事件可能指示高網絡延遲(除其他因素外)。
?
??? 另一件要注意的重要的事情是,WAIT_TIME 的值為 -2。某些平臺(如 Windows)不支持快速計時機制。如果在這些平臺上沒有設定初始化參數 TIMED_STATISTICS,那么將無法獲得準確的計時統計數據。在這種情況下,在 Oracle9i 中,該列將顯示一個非常大的數字,這使問題變得更加不清晰。在 10g 中,值 -2 指示這種情況 — 平臺不支持快速定時機制并且沒有設定 TIMED_STATISTICS。(對于本文剩下的部分,我們將假定存在一個快速計時機制。)
?
?
會話也顯示等待
?
??? 記得長期以來一直需要將 V$SESSION_WAIT 與 V$SESSION 結合使用以獲得有關會話的其他詳細信息嗎?嗯,這已經成為歷史了。在 10g 中,V$SESSION 視圖還顯示由 V$SESSION_WAIT 顯示的等待。下面是 V$SESSION 視圖其余的列,這些列顯示了會話當前等待的等待事件。
?
EVENT#???????????????????? NUMBER
EVENT????????????????????? VARCHAR2(64)
P1TEXT???????????????????? VARCHAR2(64)
P1???????????????????????? NUMBER
P1RAW????????????????????? RAW(4)
P2TEXT???????????????????? VARCHAR2(64)
P2???????????????????????? NUMBER
P2RAW????????????????????? RAW(4)
P3TEXT???????????????????? VARCHAR2(64)
P3???????????????????????? NUMBER
P3RAW????????????????????? RAW(4)
WAIT_CLASS_ID????????????? NUMBER
WAIT_CLASS#??????????????? NUMBER
WAIT_CLASS???????????????? VARCHAR2(64)
WAIT_TIME????????????????? NUMBER
SECONDS_IN_WAIT??????????? NUMBER
STATE????????????????????? VARCHAR2(19)
??? 這些列與 V$SESSION_WAIT 中的那些列相同,且顯示相同的信息,從而不再需要在那個視圖中查看它們了。因此,對于等待任意事件的任意會話,您僅需要查看一個視圖。
?
??? 讓我們回到原來的問題:SID 為 269 的會話正等待事件 enq:TX — row lock contention,指示它正等待被另一個會話占用的鎖。要診斷該問題,您必須識別占用鎖的那個會話。但您如何才能做到這一點?
?
??? 在 Oracle9i 及更低版本中,您可能得編寫復雜(和極耗資源)的查詢來獲得占用鎖的會話的 SID。而在 10g 中,您所要做的就是執行以下查詢:
?
select BLOCKING_SESSION_STATUS, BLOCKING_SESSION
from v$session
where sid = 269
?
BLOCKING_SE BLOCKING_SESSION
----------- ----------------
VALID??????????????????? 265
??? 找到了:SID 為 265 的會話阻塞了會話 269。還能更容易嗎?
?
?
有多少等待?
?
??? 用戶仍然在纏著您,因為用戶的問題仍然沒有得到滿意的解答。為什么用戶的會話花了這么長時間才完成?您可以執行以下命令來找出原因:
?
select * from v$session_wait_class where sid = 269;
??? 輸出返回為:
?
SID SERIAL# WAIT_CLASS_ID WAIT_CLASS# WAIT_CLASS??? TOTAL_WAITS TIME_WAITED
---- ------- ------------- ----------- ------------- ----------- -----------
269??? 1106??? 4217450380?????????? 1 Application?????????? 873????? 261537
269??? 1106??? 3290255840?????????? 2 Configuration?????????? 4?????????? 4
269??? 1106??? 3386400367?????????? 5 Commit????????????????? 1?????????? 0
269??? 1106??? 2723168908?????????? 6 Idle?????????????????? 15????? 148408
269??? 1106??? 2000153315?????????? 7 Network??????????????? 15?????????? 0
269??? 1106??? 1740759767?????????? 8 User I/O?????????????? 26?????????? 1
?
??? 注意這里有關會話等待的大量信息?,F在您知道了,該會話已經為與應用程序相關的等待等待了 873 次(共 261,537 厘秒),在與網絡相關的事件中等待了 15 次等等。
?
??? 以此類推,您可以使用以下查詢來查看系統范圍的等待類的統計數據。同樣,時間是以厘秒為單位的。
?
select * from v$system_wait_class;
?
WAIT_CLASS_ID WAIT_CLASS# WAIT_CLASS??? TOTAL_WAITS TIME_WAITED
------------- ----------- ------------- ----------- -----------
1893977003?????????? 0 Other??????????????? 2483?????? 18108
4217450380?????????? 1 Application????????? 1352????? 386101
3290255840?????????? 2 Configuration????????? 82???????? 230
3875070507?????????? 4 Concurrency??????????? 80???????? 395
3386400367?????????? 5 Commit?????????????? 2625??????? 1925
2723168908?????????? 6 Idle?????????????? 645527?? 219397953
2000153315?????????? 7 Network????????????? 2125?????????? 2
1740759767?????????? 8 User I/O???????????? 5085??????? 3006
4108307767?????????? 9 System I/O???????? 127979?????? 18623
?
??? 大多數問題不是孤立出現的;它們留下了揭示真相的線索,模式可以識別這些線索。可以按如下方式從等待類的一個歷史視圖中查看模式。
?
select * from v$waitclassmetric;
?
??? 這個視圖存儲了最后一分鐘內與等待類相關的統計數據。
?
select wait_class#, wait_class_id,
average_waiter_count "awc", dbtime_in_wait,
time_waited,? wait_count
from v$waitclassmetric
/
?
WAIT_CLASS# WAIT_CLASS_ID? AWC DBTIME_IN_WAIT TIME_WAITED WAIT_COUNT
----------- ------------- ---- -------------- ----------- ----------
????????? 0??? 1893977003??? 0????????????? 0?????????? 0????????? 1
????????? 1??? 4217450380??? 2???????????? 90??????? 1499????????? 5
????????? 2??? 3290255840??? 0????????????? 0?????????? 4????????? 3
????????? 3??? 4166625743??? 0????????????? 0?????????? 0????????? 0
????????? 4??? 3875070507??? 0????????????? 0?????????? 0????????? 1
????????? 5??? 3386400367??? 0????????????? 0?????????? 0????????? 0
????????? 6??? 2723168908?? 59????????????? 0????? 351541??????? 264
????????? 7??? 2000153315??? 0????????????? 0?????????? 0???????? 25
????????? 8??? 1740759767??? 0????????????? 0?????????? 0????????? 0
????????? 9??? 4108307767??? 0????????????? 0?????????? 8??????? 100
???????? 10??? 2396326234??? 0????????????? 0?????????? 0????????? 0
???????? 11??? 3871361733??? 0????????????? 0?????????? 0????????? 0
?
??? 注意 WAIT_CLASS_ID 和相關的統計數據。對于值 4217450380,我們看到 2 個會話在最后一分鐘內總共等待了該類 5 次(1,499 厘秒)。但該等待類是什么?您可以從 V$SYSTEM_WAIT_CLASS 中獲取這一信息(如上所示)— 就是 Application 類。
?
??? 注意名稱為 DBTIME_IN_WAIT 的列,這是一個非常有用的列。在我們第 6 周關于自動工作負載信息庫 (AWR) 的部分中,您可能還記得在 10g 中是以更細?;姆绞絹韴蟾鏁r間的,并且可以確定在數據庫中花費的準確時間。DBTIME_IN_WAIT 顯示在數據庫中花費的時間。
?
?
一切都留有線索
?
??? 用戶終于離開了,您長舒了一口氣。但您可能仍然想尋根究底,希望查明主要是哪些等待造成用戶會話中的問題。當然,您可以通過查詢 V$SESSION_WAIT 而輕易地得到答案 — 但不幸的是,等待事件現在不存在了,因此該視圖沒有它們的任何記錄。您該怎么辦?
?
??? 在 10g 中,自動保留活動會話最后 10 個事件的會話等待歷史。這個歷史可通過 V$SESSION_WAIT_HISTORY 視圖查看。要找出這些事件,您可以簡單地執行:
?
select event, wait_time, wait_count
from v$session_wait_history
where sid = 265
/
?
EVENT?????????????????????????? WAIT_TIME WAIT_COUNT
------------------------------ ---------- ----------
log file switch completion????????????? 2????????? 1
log file switch completion????????????? 1????????? 1
log file switch completion????????????? 0????????? 1
SQL*Net message from client???????? 49852????????? 1
SQL*Net message to client?????????????? 0????????? 1
enq:TX - row lock contention????????? 28????????? 1
SQL*Net message from client?????????? 131????????? 1
SQL*Net message to client?????????????? 0????????? 1
log file sync?????????????????????????? 2????????? 1
log buffer space??????????????????????? 1????????? 1
??? 當會話變為非活動狀態或斷開時,記錄從該視圖中消失。不過,這些等待的歷史保留在 AWR 表中,以便進一步分析。從 AWR 中顯示會話等待的視圖是 V$ACTIVE_SESSION_HISTORY。(同樣,有關 AWR 的更多信息,請參考本系列的第 6 周。)
?
?
結論
?
??? 通過 Oracle 數據庫 10g 中的等待模型的增強,分析性能問題變得非常容易。提供的會話等待歷史可以幫助您在會話經歷等待后診斷問題。將等待歸為各種等待類還有助于您了解每種類型等待所造成的影響,這在研究正確的糾正方法時將帶來便利。
?
?
有關等待事件動態性能視圖和等待事件本身的更多信息,請參考《Oracle 數據庫性能調整指南 10g 第 1 版 (10.1)》的第 10 章。
?
?
?
?