2012-07-26 52 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