Job長時間執行不能退出的分析

witus發表於2008-01-29

今天接到公司運維人員反映說在一臺DB上執行grant execute on DBMS_LOCK to xxx操作特別慢,等待了很長時間都不能執行完成。
我登入到資料上執行了一下,5分鐘後,執行還沒用完成,便手動結束了。然後嘗試執行grant別的許可權,發現很快就執行完成了, 只有執行grant execute on DBMS_LOCK to xxx的時候特別慢。再次執行,在大約10分鐘後,丟擲錯誤ORA-04021: timeout occurred while waiting to lock object SYS.DBMS_LOCK。看來是由於DBMS_LOCK包被鎖了,導致執行grant慢。
從v$access檢視中檢視到佔用DBMS_LOCK的使用者:
SQL> select * from v$access where object like '%LOCK%';

SID OWNER OBJECT TYPE
---------- ---------- ------------------------------ ------------------------
34 SYS DBMS_LOCK PACKAGE
34 SYS DBMS_LOCK_ALLOCATED TABLE
34 SYS DBMS_LOCK_ID CURSOR

透過SID查詢到程式,發現是一個JOB正在執行。該JOB是實現複製事務推送的PUSH程式。

從v$session中還查詢到:
SQL> select sid,last_call_et from v$session where sid=34;

SID LAST_CALL_ET
---------- ------------
34 37329

該JOB已經執行了10個多小時。

但是查詢該job的定義:
SQL> select * from dba_jobs where job=11;

JOB NEXT_DATE NEXT_SEC INTERVAL
---------- ----------------- ---------------- --------------------------------------------------
WHAT
------------------------------------------------------------------------------------------------------------------------------------
11 20080129 12:15:10 12:15:10 /*5:Secs*/ sysdate + 5/(60*60*24)
declare rc binary_integer; begin rc := sys.dbms_defer_sys.push(destination=>'SDWTDB1', delay_seconds=>5, parallelism=>1); end;

從中可以看出,該job的執行間隔是5秒鐘,現網中需要複製的事務雖然多但是也不需要連續推送10個小時,而且從伺服器的CPU觀察,複製量遠沒用達到伺服器的負荷,效能還不錯。那麼job執行這麼長時間不退出,不正常。

考慮到dbms_defer_sys.push過程中delay_seconds引數的作用。job在執行完成後並不立即退出,還需要等待delay_seconds秒後,再次檢查複製佇列,如果為空,則退出退出。它的作用是避免在一個迴圈快的程式中頻繁呼叫job。
觀察現網中複製事務出現的速度,基本上每秒鐘都用新的複製事務出現,這樣,job在執行完後,過5秒,發現又有新的事務,再執行,再過5秒檢查,再發現新的事務,再執行,再等5秒...... 如此迴圈,job不能退出。
嘗試將delay_seconds引數修改為0,然後再觀察,發現job每隔5秒執行一次,並且馬上退出。再查詢此時複製事務積壓的情況,只有不到10個,比修改前平均積壓50個快很多。

因此可知,Job長時間不能退出的原因是push過程的delay_seconds引數設定為5造成的。在複製事務出現比較頻繁的資料庫中,建議將該引數修改為0.

Job能迅速退出後,在執行grant execute on DBMS_LOCK to xxx,很快退出。

至此,問題得到解決。

[@more@]

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

相關文章