2012-07-26 23 views
17

Próbuję zrozumieć problem, który mamy z zawieszonym procesem Java. Proces ten był produkowany przez około 4 miesiące, a na początku tego tygodnia zaczął się zawieszać. Kiedy patrzę na wysypisko gwintu procesie wszystkich istotnych wątków (3) mają stosy tak:Rozwiązywanie problemów z procesem zawieszonym przez 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) 

Brak wątków czekających na zamki więc proces nie jest w impasie. Te 3 wątki, które wykonują zadanie, są po prostu blokowane, czekając na odpowiedź Oracle, przynajmniej tak to dla mnie wygląda.

Patrząc na Oracle, gdy wysyłam zapytanie do sesji $ $, wygląda na to, że jeden z połączeń powiązanych z tymi wątkami wykonuje aktualnie zapytanie, mimo że nie widzę 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 

Moje pytania są następujące:

  1. Am I poprawić w mojej analizy wynika, że ​​proces ten jest po prostu zablokowany czekając na odpowiedź z Oracle?
  2. Czego powinienem szukać w Oracle, aby zrozumieć, dlaczego ten proces jest blokowany?

Aktualizacja:

podstawie komentarzu dotyczącym patrząc w DBA_WAITERS i DBA_LOCKS

select * from dba_waiters; 

no rows selected 

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

no rows selected 

Było 98 wierszy w dba_locks ale ponieważ wszystkie są 'nie Blocking' Nie sądzę, że jest to problem z blokowaniem? Omawiany proces był w tym stanie przez ponad 3 godziny, więc doszło już do impasu.

Jestem z teorii, że instancja Oracle nie jest "zdrowy", ale nie mam pojęcia, na co patrzeć. Mam prośbę o ponowne uruchomienie serwera Oracle, ale to jeszcze nie zostało zrobione.

Pytanie uzupełniające: czy normalne jest, że sesja v $ zawiera identyfikator sql_id, który nie istnieje w v $ sql, a jeśli tak, to w jakich warunkach?

+2

"wisiał" hehehehehe;] – mre

+1

to racja - mój proces jest większy niż twój proces. ;) – sceaj

+0

Czy proces prawdopodobnie wykonuje jakieś aktualizacje, czy też jest to zapytanie? Jeśli się aktualizuje, czy coś innego może blokować to, co próbuje zrobić? Zacznę od sprawdzenia, czy 'DBA_WAITERS' lub' DBA_LOCKS' pokazuje coś interesującego. –

Odpowiedz

9

Problem został rozwiązany, a odpowiedź była właściwa w tabeli v $ sesja. Podobno sesje Oracle mogą blokować z powodów innych niż samo blokowanie. Zwróć uwagę na kolumnę FINAL_BLOCKING_SESSION - identyfikuje sesję, która jest podstawową przyczyną blokowania. Sprawdziliśmy sesję 845 i stwierdziliśmy, że proces klienta (zidentyfikowany przez MASZYNĘ i PORT) już nie istnieje. DBA zabił sesję 845 i wszystkie wróciły do ​​normy.

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

Czy możesz wyjaśnić, w jaki sposób zostały przefiltrowane i zidentyfikowane, że te trzy wpisy są podstawową przyczyną blokowania? Co ich rozdali? Mam dokładnie ten sam problem. Dzięki. –

+1

3 podane wpisy nie są podstawową przyczyną - są to sesje Oracle z mojej aplikacji, które zostały zablokowane. Jeśli przewiniesz w prawo i spojrzysz na kolumny BLOCKING_SESSION i FINAL_BLOCKING_SESSION, zobaczysz tam wartości SID. Kiedy badaliśmy SID 845 (FINAL_BLOCKING_SESSION) sesja była dla klienta, który już nie istniał - z jakiegoś powodu Oracle nie był w stanie wykryć, że proces klienta zniknął. – sceaj

+0

@sceaj - obecnie doświadczamy tego samego problemu. Słusznie zidentyfikowaliście problem, ale nie jest to przyczyną. Jesteśmy również na tym etapie, a obejście problemu polegałoby na zabiciu sesji, ale musimy zrozumieć, dlaczego Oracle i sesja klienta nie są zsynchronizowane. Jesteśmy przekonani, że istnieje pewien "blip" sieci, który to spowodował. Podczas gdy zespół sieciowy analizuje problem niedopełnienia komunikacji. DEV postanowiliśmy wprowadzić "timeout odczytu", który sprawi, że połączenie będzie bardziej odporne. –

-3

Jeśli sama instancja jest "niezdrowa", ponowne uruchomienie serwera Oracle powinno rozwiązać ten problem i przywrócić go do zdrowego stanu. Do tego czasu można skonfigurować moduł równoważenia obciążenia HTTP, aby sprawdzić kondycję różnych instancji, odpytując adres URL i zwracając wynik od 100 do 500 dla zdrowej sesji.

+3

Jestem całkowicie zaskoczony, co twoja sugestia jest i jak to pomaga? Pomocne mogą być bezpośrednie kroki w celu zidentyfikowania przyczyny blokowania - nie chcę zakładać, że ponowne uruchomienie rozwiąże problem tylko po to, aby dowiedzieć się, że dokładnie ten sam problem istnieje po ponownym uruchomieniu komputera. – sceaj

2

ja również napotkał ten problem niedawno, i użył tego zapytania znaleźć blokowania/zablokowany sesje w Oracle:

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; 

Źródło: http://www.dba-oracle.com/t_final_blocking_session_final_blocking_instance.htm

Powiązane problemy