[Oracle10G新特性]_11.等待界面
?
??? 這一篇主要內(nèi)容就是關(guān)于Oracle的等待, 本文列舉了各個關(guān)于Oracle內(nèi)部記錄等待信息的視圖及其意義。不過這個問題不常遇到,暫時還沒有可以進(jìn)行實(shí)際應(yīng)用的可能。暫時先學(xué)習(xí)一下,等以后有需要再回來仔細(xì)研究一下。
?
----------------------------------------------------------
等待界面
?
10g 等待界面為還沒有被 ADDM 捕獲的即時性能問題提供了有價值的診斷數(shù)據(jù)
?
??? “數(shù)據(jù)庫太慢了!”
?
??? 這句話通常出自一位嚴(yán)格的用戶之口。如果您和我一樣,那么在您的 DBA 生涯中您肯定無數(shù)次聽到過這句話。
??? 那么,您又怎樣解決該問題呢?除了對用戶置之不理之外(這是我們大多數(shù)人都不敢奢望的想法),您可能要做的第一件事就是查看是否有任何會話在等待數(shù)據(jù)庫內(nèi)部或外部的任何事件。
?
??? Oracle 提供了一個簡單但一流的機(jī)制來達(dá)到此目的:V$SESSION_WAIT 視圖。該視圖顯示了有助于您的診斷的各種信息,如一個會話正在等待或已經(jīng)等待的事件,以及等待了多長時間和多少次。例如,如果會話在等待事件 "db file sequential read",列 P1 和 P2 將顯示會話正在等待的塊的 file_id 和 block_id。
?
??? 對于大多數(shù)等待事件而言,這個視圖足夠了,但它還不是一個強(qiáng)健的調(diào)整工具,之所以如此說,至少是因?yàn)橐韵聝蓚€重要原因:
?
??? ● 該視圖是當(dāng)前情況的一個快照。當(dāng)?shù)却辉俅嬖跁r,會話先前出現(xiàn)的那些等待的歷史也將消失,從而使得事后診斷非常困難。V$SESSION_EVENT 提供了累積的但不是非常詳細(xì)的數(shù)據(jù)。
??? ● V$SESSION_WAIT 包含了只與等待事件相關(guān)的信息;要獲得所有其它的相關(guān)信息(如用戶 ID 和終端),您必須將它和 V$SESSION 視圖結(jié)合使用。
?
??? 在 Oracle 數(shù)據(jù)庫 10g 中,等待界面經(jīng)過了徹底的重新設(shè)計(jì),從而只需更少的 DBA 干預(yù)即可提供更多的信息。在本文中,我們將瀏覽這些新的特性,并了解它們?nèi)绾螏椭覀冊\斷性能問題。對于大多數(shù)性能問題,您可以從自動數(shù)據(jù)庫診斷管理器 (ADDM) 中獲得擴(kuò)展分析,但對于還沒有被 ADDM 捕獲的即時問題,等待界面將提供有價值的診斷數(shù)據(jù)。
?
?
增強(qiáng)的會話等待
?
??? 第一個增強(qiáng)涉及到 V$SESSION_WAIT 本身。這一點(diǎn)通過示例可以很好地說明。
?
??? 假定您的用戶抱怨會話掛起了。您查明了該會話的 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,這表示它是一個需要您注意的等待。
?
??? 該列突出顯示那些能夠證明與您的調(diào)整最相關(guān)的少數(shù)幾條記錄。例如,您可以使用如下查詢來獲取事件的等待會話。
?
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 事件。您可以將它們作為非阻塞等待消除掉;不過,有時這些“空閑”事件可能指示一個內(nèi)在的問題。例如,與 SQL*Net 相關(guān)的事件可能指示高網(wǎng)絡(luò)延遲(除其他因素外)。
?
??? 另一件要注意的重要的事情是,WAIT_TIME 的值為 -2。某些平臺(如 Windows)不支持快速計(jì)時機(jī)制。如果在這些平臺上沒有設(shè)定初始化參數(shù) TIMED_STATISTICS,那么將無法獲得準(zhǔn)確的計(jì)時統(tǒng)計(jì)數(shù)據(jù)。在這種情況下,在 Oracle9i 中,該列將顯示一個非常大的數(shù)字,這使問題變得更加不清晰。在 10g 中,值 -2 指示這種情況 — 平臺不支持快速定時機(jī)制并且沒有設(shè)定 TIMED_STATISTICS。(對于本文剩下的部分,我們將假定存在一個快速計(jì)時機(jī)制。)
?
?
會話也顯示等待
?
??? 記得長期以來一直需要將 V$SESSION_WAIT 與 V$SESSION 結(jié)合使用以獲得有關(guān)會話的其他詳細(xì)信息嗎?嗯,這已經(jīng)成為歷史了。在 10g 中,V$SESSION 視圖還顯示由 V$SESSION_WAIT 顯示的等待。下面是 V$SESSION 視圖其余的列,這些列顯示了會話當(dāng)前等待的等待事件。
?
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,指示它正等待被另一個會話占用的鎖。要診斷該問題,您必須識別占用鎖的那個會話。但您如何才能做到這一點(diǎn)?
?
??? 在 Oracle9i 及更低版本中,您可能得編寫復(fù)雜(和極耗資源)的查詢來獲得占用鎖的會話的 SID。而在 10g 中,您所要做的就是執(zhí)行以下查詢:
?
select BLOCKING_SESSION_STATUS, BLOCKING_SESSION
from v$session
where sid = 269
?
BLOCKING_SE BLOCKING_SESSION
----------- ----------------
VALID??????????????????? 265
??? 找到了:SID 為 265 的會話阻塞了會話 269。還能更容易嗎?
?
?
有多少等待?
?
??? 用戶仍然在纏著您,因?yàn)橛脩舻膯栴}仍然沒有得到滿意的解答。為什么用戶的會話花了這么長時間才完成?您可以執(zhí)行以下命令來找出原因:
?
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
?
??? 注意這里有關(guān)會話等待的大量信息。現(xiàn)在您知道了,該會話已經(jīng)為與應(yīng)用程序相關(guān)的等待等待了 873 次(共 261,537 厘秒),在與網(wǎng)絡(luò)相關(guān)的事件中等待了 15 次等等。
?
??? 以此類推,您可以使用以下查詢來查看系統(tǒng)范圍的等待類的統(tǒng)計(jì)數(shù)據(jù)。同樣,時間是以厘秒為單位的。
?
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
?
??? 大多數(shù)問題不是孤立出現(xiàn)的;它們留下了揭示真相的線索,模式可以識別這些線索。可以按如下方式從等待類的一個歷史視圖中查看模式。
?
select * from v$waitclassmetric;
?
??? 這個視圖存儲了最后一分鐘內(nèi)與等待類相關(guān)的統(tǒng)計(jì)數(shù)據(jù)。
?
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 和相關(guān)的統(tǒng)計(jì)數(shù)據(jù)。對于值 4217450380,我們看到 2 個會話在最后一分鐘內(nèi)總共等待了該類 5 次(1,499 厘秒)。但該等待類是什么?您可以從 V$SYSTEM_WAIT_CLASS 中獲取這一信息(如上所示)— 就是 Application 類。
?
??? 注意名稱為 DBTIME_IN_WAIT 的列,這是一個非常有用的列。在我們第 6 周關(guān)于自動工作負(fù)載信息庫 (AWR) 的部分中,您可能還記得在 10g 中是以更細(xì)粒化的方式來報(bào)告時間的,并且可以確定在數(shù)據(jù)庫中花費(fèi)的準(zhǔn)確時間。DBTIME_IN_WAIT 顯示在數(shù)據(jù)庫中花費(fèi)的時間。
?
?
一切都留有線索
?
??? 用戶終于離開了,您長舒了一口氣。但您可能仍然想尋根究底,希望查明主要是哪些等待造成用戶會話中的問題。當(dāng)然,您可以通過查詢 V$SESSION_WAIT 而輕易地得到答案 — 但不幸的是,等待事件現(xiàn)在不存在了,因此該視圖沒有它們的任何記錄。您該怎么辦?
?
??? 在 10g 中,自動保留活動會話最后 10 個事件的會話等待歷史。這個歷史可通過 V$SESSION_WAIT_HISTORY 視圖查看。要找出這些事件,您可以簡單地執(zhí)行:
?
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
??? 當(dāng)會話變?yōu)榉腔顒訝顟B(tài)或斷開時,記錄從該視圖中消失。不過,這些等待的歷史保留在 AWR 表中,以便進(jìn)一步分析。從 AWR 中顯示會話等待的視圖是 V$ACTIVE_SESSION_HISTORY。(同樣,有關(guān) AWR 的更多信息,請參考本系列的第 6 周。)
?
?
結(jié)論
?
??? 通過 Oracle 數(shù)據(jù)庫 10g 中的等待模型的增強(qiáng),分析性能問題變得非常容易。提供的會話等待歷史可以幫助您在會話經(jīng)歷等待后診斷問題。將等待歸為各種等待類還有助于您了解每種類型等待所造成的影響,這在研究正確的糾正方法時將帶來便利。
?
?
有關(guān)等待事件動態(tài)性能視圖和等待事件本身的更多信息,請參考《Oracle 數(shù)據(jù)庫性能調(diào)整指南 10g 第 1 版 (10.1)》的第 10 章。
?
?
?
?