如何診斷和解決CPU高度消耗(100%)的資料庫問題
2008-05-24 13:46
很多時候我們的伺服器可能會經曆CPU消耗100%的性能問題.
排除系統的異常,這類問題通常都是因為系統中存在性能低下甚至存在錯誤的SQL語句, 消耗了大量的CPU所緻.
本文通過一個案例就如何捕獲這樣的SQL給出一個通用的方法.
問題描述:系統CPU高度消耗,系統運作緩慢
OS:Sun Solaris8
Oracle:Oracle9203
1.首先通過Top指令檢視
我們發現在進城清單裡,存在兩個高CPU耗用的Oracle進城,分别消耗了47.77%和40.98%的CPU資源.
2.找到存在問題的程序資訊
确認這是兩個遠端連接配接的使用者程序.
3.熟悉一下我的getsql.sql腳本
注意這裡我們涉及了3個視圖,并應用其關聯進行資料擷取.
首先需要輸入一個pid,這個pid即process id,也就是在Top或ps中我們看到的PID.
通過pid和v$process.spid相關聯我們可以獲得Process的相關資訊
進而通過v$process.addr和v$session.paddr相關聯,我們就可以獲得和session相關的所有資訊.
再結合v$sqltext,我們即可獲得目前session正在執行的SQL語句.
通過v$process視圖,我們得以把作業系統和資料庫關聯了起來.
4.連接配接資料庫,找到問題sql及程序
通過Top中我們觀察到的PID,進而應用我的getsql腳本,我們得到以下結果輸出.
那麼這段代碼就是目前正在瘋狂消耗CPU的罪魁禍首.
接下來需要進行的工作就是找出這段代碼的問題,看是否可以通過優化提高其效率,減少資源消耗.
5.進一步的我們可以通過dbms_system包跟蹤該程序
SQL> @getsid
Enter value for spid: 20521
old 3: select addr from v$process where spid = &spid)
new 3: select addr from v$process where spid = 20521)
SID SERIAL# USERNAME MACHINE
----------------------------------------------------------------
45 38991 HSUSER_V51 hswapjsptl1.hurray.com.cn
SQL> exec dbms_system.set_sql_trace_in_session(45,38991,true);
PL/SQL procedure successfully completed.
SQL> !
這部分内容可以參考:
<a href="http://www.eygle.com/case/sql_trace_1.htm">http://www.eygle.com/case/sql_trace_1.htm</a>
對于Windows上的類似問題,可以參考:
<a href="http://www.eygle.com/faq/Use.Nt.tools.manage.Oracle.htm">http://www.eygle.com/faq/Use.Nt.tools.manage.Oracle.htm</a>
6.一點說明
很多時候,高CPU消耗都是由于問題SQL導緻的,是以找到這些SQL通常也就找到了問題所在,通過優化調整
通常就可以解決問題。
但是有時候你可能會發現,這些最消耗CPU的程序是背景程序,這一般是由于異常、BUG或者恢複後的異常
導緻的,需要具體問題具體分析了.