2012-07-26 53 views
17

我想了解我們掛起的Java進程遇到的問題。這個過程已經在生產中運行了大約4個月,本週早些時候它開始掛起。當我在看的過程中的線程轉儲全部線程相關的(3)具有堆棧如下所示:疑難解答Oracle - 掛起的進程

"TxnParser_1" prio=6 tid=0x69bd3400 nid=0x2534 runnable [0x6aa2f000] 
    java.lang.Thread.State: RUNNABLE 
     at java.net.SocketInputStream.socketRead0(Native Method) 
     at java.net.SocketInputStream.read(SocketInputStream.java:129) 
     at oracle.net.ns.Packet.receive(Unknown Source) 
     at oracle.net.ns.DataPacket.receive(Unknown Source) 
     at oracle.net.ns.NetInputStream.getNextPacket(Unknown Source) 
     at oracle.net.ns.NetInputStream.read(Unknown Source) 
     at oracle.net.ns.NetInputStream.read(Unknown Source) 
     at oracle.net.ns.NetInputStream.read(Unknown Source) 
     at oracle.jdbc.driver.T4CMAREngine.unmarshalUB1(T4CMAREngine.java:1099) 
     at oracle.jdbc.driver.T4CMAREngine.unmarshalSB1(T4CMAREngine.java:1070) 
     at oracle.jdbc.driver.T4C8Oall.receive(T4C8Oall.java:478) 
     at oracle.jdbc.driver.T4CStatement.doOall8(T4CStatement.java:207) 
     at oracle.jdbc.driver.T4CStatement.executeForDescribe(T4CStatement.java:790) 
     at oracle.jdbc.driver.OracleStatement.executeMaybeDescribe(OracleStatement.java:1039) 
     at oracle.jdbc.driver.T4CStatement.executeMaybeDescribe(T4CStatement.java:830) 
     at oracle.jdbc.driver.OracleStatement.doExecuteWithTimeout(OracleStatement.java:1132) 
     at oracle.jdbc.driver.OracleStatement.executeInternal(OracleStatement.java:1687) 
     at oracle.jdbc.driver.OracleStatement.execute(OracleStatement.java:1653) 
     - locked <0x40e22f88> (a oracle.jdbc.driver.T4CStatement) 
     - locked <0x28f8d398> (a oracle.jdbc.driver.T4CConnection) 
     at com.gcg.data.LogParsingInfo.initFromDB(LogParsingInfo.java:262) 
     at com.gcg.om.OmQueueEntry.initParseInfoFromDB(OmQueueEntry.java:104) 
     at com.gcg.om.GenericQueueEntry.run(GenericQueueEntry.java:237) 
     at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886) 
     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908) 
     at java.lang.Thread.run(Thread.java:619) 

沒有線程等待鎖使過程沒有陷入僵局。這三個正在做這項工作的線程只是等待Oracle的響應,至少這是我看起來的樣子。

縱觀Oracle,當我查詢v $ session時,它看起來像是與這些線程相關的一個連接當前正在執行查詢,儘管我看不到sql。

select ... from v$session where ...; 
SQL_ADDRESS  SQL_HASH_VALUE SQL_ID  SQL_CHILD_NUMBER SQL_EXEC_START SQL_EXEC_ID PREV_SQL_ADDR PREV_HASH_VALUE PREV_SQL_ID PREV_CHILD_NUMBER PREV_EXEC_START PREV_EXEC_ID 
---------------- -------------- ------------- ---------------- -------------- ----------- ---------------- --------------- ------------- ----------------- --------------- ------------ 
       00    0               0000000239F59EE8  1483377872 fqr8pndc6p36h     5 26-JUL-12   32080545 
       00    0               0000000239F59EE8  1483377872 fqr8pndc6p36h     5 26-JUL-12   32080546 
0000000148CABD88  1784444892 a16hxxtp5sxyw            0000000239F59EE8  1483377872 fqr8pndc6p36h     5 26-JUL-12   32080544 

select * from v$sql where sql_id = 'a16hxxtp5sxyw'; 

no rows selected 

我的問題是:

  1. 我是在我的分析是正確的,該過程僅僅是阻塞等待甲骨文迴應?
  2. 我應該在Oracle中尋找什麼來理解爲什麼這個過程被阻塞?

更新時間:

基於關於在尋找DBA_WAITERS和評論DBA_LOCKS

select * from dba_waiters; 

no rows selected 

select * from dba_locks where BLOCKING_OTHERS <> 'Not Blocking'; 

no rows selected 

有98排在dba_locks但因爲所有人都「不阻止」我不認爲這是鎖定問題?有關進程已經處於這種狀態3個多小時,所以現在已經發現任何死鎖。

我的理論是Oracle實例不是「健康的」,但我不知道該看什麼。我有重新啓動Oracle服務器的請求,但尚未完成。

後續問題:v $ session中包含的sql_id在v $ sql中是否存在,如果是這樣,在什麼條件下是否正常?

+2

「掛起」 hehehehehe] – mre 2012-07-26 16:53:49

+1

這正確 - 我的過程比你的過程要大。 ;) – sceaj 2012-07-26 17:05:47

+0

該進程是否可能進行任何更新,還是隻是查詢?如果它正在更新,那麼其他任何東西都可能會鎖定它試圖執行的任何操作?我首先看看'DBA_WAITERS'或'DBA_LOCKS'是否顯示有趣的內容。 – 2012-07-26 17:25:33

回答

9

問題已解決,答案在v $ session表中正確。顯然Oracle會話可能因爲鎖定以外的原因而被阻塞。注意FINAL_BLOCKING_SESSION列 - 它標識了阻塞的根本原因。 我們調查了會話845,發現客戶端進程(由MACHINE和PORT標識)不再存在。 DBA終止會話845並全部恢復正常。

SID  SERIAL# STATUS PROGRAM   TYPE SQL_ID  PREV_SQL_ID BLOCKING_SESSION_STATUS BLOCKING_INSTANCE BLOCKING_SESSION FINAL_BLOCKING_SESSION_STATUS FINAL_BLOCKING_INSTANCE FINAL_BLOCKING_SESSION EVENT 
------- ------- --------- ---------------- ---- ------------- -------------- ----------------------- ----------------- ---------------- ----------------------------- ----------------------- ---------------------- ---------------------------- 
108 22447 ACTIVE Gcg log parser 1 USER    fqr8pndc6p36h VALID     1     1581    VALID       1      845     library cache: mutex X 
639 40147 ACTIVE Gcg log parser 3 USER    fqr8pndc6p36h VALID     1     1581    VALID       1      845     library cache: mutex X 
742 34683 ACTIVE Gcg log parser 2 USER a16hxxtp5sxyw fqr8pndc6p36h VALID     1     1581    VALID       1      845     library cache: mutex X 
+0

你能否澄清你如何過濾和確定這三個條目是阻塞的根本原因?什麼讓他們離開了?我有完全相同的問題。謝謝。 – 2016-05-20 15:53:53

+1

顯示的3個條目不是根本原因 - 它們是來自我的應用程序的Oracle會話被阻止。如果您滾動到右側並查看BLOCKING_SESSION和FINAL_BLOCKING_SESSION列,您會看到那裏有SID值。當我們調查SID 845(FINAL_BLOCKING_SESSION)時,會話是針對不再存在的客戶端 - 由於某種原因,Oracle無法檢測到客戶端進程已經消失。 – sceaj 2016-05-20 21:31:03

+0

@sceaj - 我們目前正在遇到同樣的問題。你的權利確定了問題會議,但它不是根源。我們也處於這個階段,解決方法是終止會話,但我們需要了解爲什麼Oracle和客戶端會話不同步。我們堅信有一些觸發此事的網絡「blip」。網絡團隊正在研究低級溝通問題。我們DEV決定引入「讀取超時」,使連接更具彈性。 – 2017-06-03 10:14:31

-3

如果實例本身是「不健康的」,那麼重新引導Oracle服務器應該解決該問題,並將其恢復到健康狀態。在此之前,您可以配置HTTP負載平衡器來檢查各種實例的健康狀況,方法是輪詢URL並返回100到500之間的結果以獲得健康的會話。

+3

我對你的建議是什麼或者它有何幫助感到十分困惑?有什麼幫助是確定阻塞原因的直接步驟 - 我不想假定重新啓動會解決問題,只有在重新啓動後才能找到完全相同的問題。 – sceaj 2012-07-26 18:45:03

2

我最近也遇到了這個問題,並用此查詢發現鎖定在甲骨文/鎖定會話:

select 
    inst_id||' '||sid||','||serial# inst_sid_s#, 
    username, 
    row_wait_obj#||','||row_wait_block#||','||row_wait_row# obj_lck, 
    blocking_session_Status||' '||blocking_instance||','||blocking_session blk_info, 
    final_blocking_session_Status||' '||final_blocking_instance||','||final_blocking_session f_blk_info, 
    event, 
    seconds_in_wait 
from 
    gv$session 
where 
    lockwait is not null 
order by 
    inst_id; 

來源: http://www.dba-oracle.com/t_final_blocking_session_final_blocking_instance.htm