Oracle数据库“真的”hang住了,可以理解为
数据库内部发生死锁。因为普通的DML死锁,Oracle服务器会自动监测它们的依赖关系,并回滚其中一个操作,终止这种相互等待的局面。而当这种死锁发生在争夺内核级别的资源(比如说是pins或latches)时,Oracle并不能自动的监测并处理这种死锁。其实很多时候,数据库并没有hang住,而只是由于数据库的性能问题,处理的时间比较长而已。
Hanganalyze工具使用内核调用,检测会话在等待什么资源,报告占有者和等待者的相互关系。另外,它还会将一些比较”interesting”的进程状态dump出来,这个取决于我们使用hanganalyze的分析级别。
$ sqlplus "/as sysdba"
SQL> oradebug setopid <SPID> -- V$PROCESS.SPID
SQL> oradebug setorapid <PID> -- V$PROCESS.PID
SQL> oradebug setmyid -- current session
SQL> oradebug setinst all --
RACSQL> oradebug unlimit -- dump file size unlimit
SQL> oradebug dump systemstate 266
SQL> oradebug hanganalyze 3
SQL> oradebug -g def hanganalyze 3 -- RAC
ORADEBUG hanganalyze <level>
等同于
ALTER SESSION SET EVENTS 'immediate trace name HANGANALYZE level <level>';
LEVEL参数:
10 Dump all processes (IGN state)
5 Level 4 + Dump all processes involved in wait chains (NLEAF state)
4 Level 3 + Dump leaf nodes (blockers) in wait chains (LEAF,LEAF_NW,IGN_DMP state)
3 Level 2 + Dump only processes thought to be in a hang (IN_HANG state)
1-2 Only HANGANALYZE output, no process dump at all
如果Level过大的话会产生大量的跟踪文件并影响系统的I/O性能,建议不要采用3级以上的跟踪。Hanganalyze报告会分作许多片断,会话片断信息总是由一个header详尽描述被提取的的会话信息。
HANGANALYZE跟踪文件分析:跟踪文件中最关键的部分是STATE OF NODES。对于9i该部分的条目结构为:
[nodenum]/cnode/sid/sess_srno/session/ospid/state/start/finish/[adjlist]/predecessor
nodenum:定义每个session的序列号
sid:session的sid
sess_srno:session的Serial#
ospid:OS的进程ID
state:node的状态
adjlist:表示blocker node
predecessor:表示waiter node
State有如下几种状态:
- IN_HANG:如果Session处于这种状态,表示Session遇到deadlock或者处于hung状态。
- LEAF/LEAF_NW:这些Session通常是“blocker”或者是等待某些资源的“slow” node,通过字段“predecessor” 可以很容易标识出这些node。
- NLEAF:这些Session通常被认为是“stuck”会话,意味着这些Session在等待某些 Session的资源。通过字段“adjlist”可以很容易的定义该进程的blocker。
- IGN/IGN_DMP:这些Session通常是IDLE Session。
Using Oradebug for System Hangs:
SQL> oradebug setmypid
SQL> oradebug unlimit
SQL> oradebug setinst all
SQL> oradebug hanganalyze 5
SQL> oradebug -g def dump systemstate 10
get a systemstate dump, these types of dumps can be obtained anytime
SQL> oradebug setmypid
SQL> oradebug unlimit
SQL> oradebug dump systemstate 10
Getting a PROCESSTATE DUMP
SQL> oradebug setospid <process ID>
SQL> oradebug unlimit
SQL> oradebug dump processstate 10
Getting a ERRORSTACKS DUMP
SQL> oradebug setospid <process ID>
SQL> oradebug unlimit
SQL> oradebug dump errorstack 3
Using ORADEBUG to Trace A Sessions
SQLSQL> ORADEBUG SETOSPID <SPID from the above query>
SQL> ORADEBUG EVENT 10046 TRACE NAME CONTEXT FOREVER, LEVEL 4
SQL> ORADEBUG EVENT 10046 TRACE NAME CONTEXT OFF
Tracing Errors Using ORADEBUG
SQL> ORADEBUG EVENT 942 TRACE NAME ERRORSTACK LEVEL 3
Using ORADEBUG to Find Semaphore and Memory Segments
$ ipcs -b
SQL> oradebug setmypid
SQL> oradebug ipc
SQL> oradebug tracefile_name
$ ipcrm <option> <id#>
$ ipcrm -m <shm_id#>
$ ipcrm -s <sem_id#>
Finding Parallel SQL Processes Using ORADEBUG
SQL> oradebug setospid <process id>
SQL> oradebug unlimit
SQL> oradebug event 10046 trace name context forever, level 4
Tracking down ORA-04030 errors
SQL> oradebug setospid <pid>
SQL> oradebug unlimit
SQL> oradebug dump heapdump 5 <--this dumps PGA and UGA heaps
Using Oradebug to Debug Spinning Processes
SQL> oradebug setospid <SPID>
SQL> oradebug unlimit
SQL> oradebug dump errorstack 3
ALTER SESSION SET EVENTS 'IMMEDIATE TRACE NAME SYSTEMSTATE LEVEL 10';
How to determine the Events Set in a System
1 for session ***** 2 for process ***** 4 for system
SQL> oradebug setmypid
SQL> oradebug dump events 4
SQL> oradebug tracefile_name
Using ORADEBUG to Release DDL locks
SQL> oradebug wakeup <pid>