本文介绍一下ORACLE数据库的调试工具ORACLE EVENT && ORADEBUG
--首先介绍下获得当前SESSION的SID、SERIAL#的几种方法:
1、select sid from v$mystat where rownum = 1;
2、select sid from v$session where audsid = userenv('sessionid');
3、select sid from v$session where audsid = sys_context('userenv','sessionid');
4、select sid from v$session where sid = dbms_support.mysid;--需要单独安装包
D:Oracleora92rdbmsadmin>sqlplus /nolog
SQL*Plus: Release 9.2.0.1.0 - Production on 星期二 6月 5 11:20:03 2007
Copyright (c) 1982, 2002, Oracle Corporation. All rights reserved.
SQL> conn /as sysdba
已连接。
SQL> @dbmssupp.sql
程序包已创建。
程序包主体已创建。
SQL> GRANT EXECUTE ON dbms_support TO PUBLIC;
授权成功。
SQL> CREATE PUBLIC SYNONYM dbms_support FOR dbms_support;
同义词已创建。
SQL> conn test/test
已连接。
SQL> select sid from v$session where sid = dbms_support.mysid;
一、ORACLE EVENT
1、“SQL TRACE”
是Oracle提供的用于进行SQL跟踪的手段,是强有力的辅助诊断工具。在日常的数据库问题诊断和解决中,“SQL TRACE”是
非常常用的方法。
在全局启用
在参数文件(pfile/spfile)中指定: SQL_TRACE = true
在全局启用SQL_TRACE会导致所有进程的活动被跟踪,包括后台进程及所有用户进程,这通常会导致比较严重的性能问题,
所以在生产环境中要谨慎使用。
在当前session级设置
SQL> alter session set SQL_TRACE=true;
会话已更改。
SQL> select * from test;
COL1 COL2 COL3
-------------------- -------------------- --------------------
00001 00002 00003
00004 00005 00006
SQL> alter session set SQL_TRACE=false;
会话已更改。
跟踪其它用户进程
SQL> exec dbms_system.set_SQL_TRACE_in_session(sid,seial#,true);
SQL> exec dbms_system.set_SQL_TRACE_in_session(sid,seial#,false);
2. 10046事件
10046事件是Oracle提供的内部事件,是对SQL_TRACE的增强.
10046事件可以设置以下四个级别:
1 - 启用标准的SQL_TRACE功能,等价于SQL_TRACE。
4 - Level 1 加上绑定值(bind values)
8 - Level 1 + 等待事件跟踪
12 - Level 1 + Level 4 + Level 8
a. 在全局设置
在参数文件中增加:
EVENT="10046 trace name context forever,level 12"
此设置对所有用户的所有进程生效、包括后台进程.
b. 对当前session设置
SQL> alter session set events '10046 trace name context forever';
SQL> alter session set events '10046 trace name context forever, level 8';
SQL> alter session set events '10046 trace name context off';
c. 对其他用户session设置
SQL> exec dbms_system.set_ev(sid,seial#,10046,12,'');
3、利用DBMS_SUPPORT包
更多内容参看:http://zhouwf0726.itpub.net/post/9689/291636
SQL>EXECUTE dbms_support.start_trace;
SQL>EXECUTE dbms_support.start_trace (BINDS=>true);
SQL>EXECUTE dbms_support.start_trace (WAITS=>true);
SQL>EXECUTE dbms_support.start_trace_in_session(25,4328,waits->true,binds=>true);
SQL>EXECUTE dbms_support.stop_trace;
SQL>EXECUTE dbms_support.stop_trace_in_session (25, 4328);
给出几个跟踪指定的SESSION的例子:
SESSION 1:
SQL> SHOW USER
USER 为"TEST"
SQL> SELECT SID,SERIAL# FROM V$SESSION WHERE SID=(select sid from v$mystat where
rownum = 1);
SID SERIAL#
---------- ----------
12 6
SESSION 2:
SQL> SHOW USER
USER 为"SYS"
SQL> EXEC DBMS_SYSTEM.SET_SQL_TRACE_IN_SESSION(12,6,TRUE);
PL/SQL 过程已成功完成。
SESSION 1:
SQL> set serveroutput on
SQL> declare
2 event_level number;
3 begin
4 for event_number in 10000..10999 loop
5 sys.dbms_system.read_ev(event_number, event_level);
6 if (event_level > 0) then
7 sys.dbms_output.put_line('Event '||to_char(event_number)||' is set at level '||to_char(event_level));
8 end if;
9 end loop;
10 end;
11 /
Event 10046 is set at level 1
PL/SQL 过程已成功完成。
SQL> SELECT * FROM TEST;
COL1 COL2 COL3
-------------------- -------------------- --------------------
00001 00002 00003
00004 00005 00006
SQL> SELECT P1.VALUE||''||P2.VALUE||'_ORA_'||P.SPID FILENAME
2 FROM
3 V$PROCESS P,
4 V$SESSION S,
5 V$PARAMETER P1,
6 V$PARAMETER P2
7 WHERE P1.NAME = 'user_dump_dest'
8 AND P2.NAME = 'db_name'
9 AND P.ADDR = S.PADDR
10 AND S.AUDSID = USERENV ('SESSIONID');
FILENAME
--------------------------------------------------------------------------------
D:oracleadminorcludumporcl_ORA_3204
3204:(可以用tkprof格式化后分析)
PARSING IN CURSOR #1 len=18 dep=0 uid=61 oct=3 lid=61 tim=5017207740 hv=3157870488 ad='650e4cf0'
SELECT * FROM TEST
END OF STMT
PARSE #1:c=93750,e=602584,p=1,cr=19,cu=0,mis=1,r=0,dep=0,og=4,tim=5017207733
EXEC #1:c=0,e=47,p=0,cr=0,cu=0,mis=0,r=0,dep=0,og=4,tim=5017238223
FETCH #1:c=0,e=442,p=1,cr=3,cu=0,mis=0,r=1,dep=0,og=4,tim=5017244533
FETCH #1:c=0,e=34,p=0,cr=1,cu=0,mis=0,r=1,dep=0,og=4,tim=5017250817
*** 2007-06-05 09:40:41.000
SESSION 2:
SQL> SHOW USER
USER 为"SYS"
SQL> EXEC DBMS_SYSTEM.SET_SQL_TRACE_IN_SESSION(12,6,FALSE);
SESSION 1:
SQL> declare
2 event_level number;
3 begin
4 for event_number in 10000..10999 loop
5 sys.dbms_system.read_ev(event_number, event_level);
6 if (event_level > 0) then
7 sys.dbms_output.put_line('Event '||to_char(event_number)||' is set at level '||to_char(event_level));
8 end if;
9 end loop;
10 end;
11 /
PL/SQL 过程已成功完成。
SESSION 2:
SQL> exec dbms_system.set_ev(12,6,10046,12,'');
PL/SQL procedure successfully completed
SESSION 1:
SQL> declare
2 event_level number;
3 begin
4 for event_number in 10000..10999 loop
5 sys.dbms_system.read_ev(event_number, event_level);
6 if (event_level > 0) then
7 sys.dbms_output.put_line('Event '||to_char(event_number)||' is set at level '||to_char(event_level));
8 end if;
9 end loop;
10 end;
11 /
Event 10046 is set at level 12
PL/SQL 过程已成功完成。
SQL> SELECT P1.VALUE||''||P2.VALUE||'_ORA_'||P.SPID FILENAME
2 FROM
3 V$PROCESS P,
4 V$SESSION S,
5 V$PARAMETER P1,
6 V$PARAMETER P2
7 WHERE P1.NAME = 'user_dump_dest'
8 AND P2.NAME = 'db_name'
9 AND P.ADDR = S.PADDR
10 AND S.AUDSID = USERENV ('SESSIONID');
FILENAME
--------------------------------------------------------------------------------
D:oracleadminorcludumporcl_ORA_3204
3204:
PARSING IN CURSOR #1 len=25 dep=0 uid=61 oct=3 lid=61 tim=6781738649 hv=1275046628 ad='64ef8a4c'
select count(*) from test
END OF STMT
PARSE #1:c=0,e=652,p=0,cr=0,cu=0,mis=1,r=0,dep=0,og=4,tim=6781738640
BINDS #1:
EXEC #1:c=0,e=117,p=0,cr=0,cu=0,mis=0,r=0,dep=0,og=4,tim=6781738874
WAIT #1: nam='SQL*Net message to client' ela= 5 p1=1111838976 p2=1 p3=0
FETCH #1:c=0,e=91,p=0,cr=3,cu=0,mis=0,r=1,dep=0,og=4,tim=6781739037
WAIT #1: nam='SQL*Net message from client' ela= 233 p1=1111838976 p2=1 p3=0
FETCH #1:c=0,e=3,p=0,cr=0,cu=0,mis=0,r=0,dep=0,og=0,tim=6781739404
WAIT #1: nam='SQL*Net message to client' ela= 3 p1=1111838976 p2=1 p3=0
SESSION 2:
SQL> exec dbms_system.set_ev(12,6,10046,0,'');
ALTER SESSION SET SQL_TRACE=TRUE;
ALTER SESSION SET TRACEFILE_IDENTIFIER=...;
select d.value||'/'||lower(rtrim(i.instance,chr(0)))||'_ora_'||p.spid||'.trc' trace_file_name
from (select p.spid
from v$mystat m, v$session s,v$process p
where m.statistic# = 1 and
s.sid = m.sid and
p.addr = s.paddr ) p,
( select t.instance
from v$thread t,v$parameter v
where v.name = 'thread' and
(v.value = 0 or t.thread# = to_number(v.value))) i,
( select value from v$parameter where name = 'user_dump_dest') d
/
获得诊断事件列表:
大部分的诊断事件的数值都是在10000至10999范围内,使用如下的脚本可以查看到所有的诊断事件:
SET SERVEROUTPUT ON
DECLARE
err_msg VARCHAR2(120);
BEGIN
dbms_output.enable (1000000);
FOR err_num IN 10000..10999
LOOP
err_msg := SQLERRM (-err_num);
IF err_msg NOT LIKE '%Message '||err_num||' not found%' THEN
dbms_output.put_line (err_msg);
END IF;
END LOOP;
END;
/
在UNIX系统中,可以在$ORACLE_HOME/rdbms/mesg/oraus.msg这个文件中找到所有的诊断事件的名称和定义。使用如下脚本可以输出所有
的详细的诊断事件的信息:
event=10000
while [ $event -ne 10999 ]
do
event=`expr $event + 1`
oerr ora $event
done
样本输出文件如下:
10001, 00000, "control file crash event1"
// *Document: NO
// *Cause:
// *Action:
10002, 00000, "control file crash event2"
// *Document: NO
// *Cause:
// *Action:
10003, 00000, "control file crash event3"
// *Document: NO
// *Cause:
// *Action:
10004, 00000, "block recovery testing - internal error"
// *Document: NO
// *Cause:
// *Action:
二、ORADEBUG
ORADEBUG is an undocumented debugging utility supplied with Oracle
For more general information see ORADEBUG introduction
In Oracle 9.2 commands include
|
The ORADEBUG HELP command lists the commands available within ORADEBUG
These vary by release and platform. Commands appearing in this help do not necessarily work for the release/platform on which the database is running
For example in Oracle 9.2.0.1 (Windows 2000) the command
ORADEBUG HELP
returns the following
| Command | Arguments | Description |
| HELP | [command] | Describe one or all commands |
| SETMYPID | Debug current process | |
| SETOSPID | <ospid> | Set OS pid of process to debug |
| SETORAPID | <orapid> ['force'] | Set Oracle pid of process to debug |
| DUMP | <dump_name> <lvl> [addr] | Invoke named dump |
| DUMPSGA | [bytes] | Dump fixed SGA |
| DUMPLIST | Print a list of available dumps | |
| EVENT | <text> | Set trace event in process |
| SESSION_EVENT | <text> | Set trace event in session |
| DUMPVAR | <p|s|uga> <name> [level] | Print/dump a fixed PGA/SGA/UGA variable |
| SETVAR | <p|s|uga> <name> <value> | Modify a fixed PGA/SGA/UGA variable |
| PEEK | <addr> <len> [level] | Print/Dump memory |
| POKE | <addr> <len> <value> | Modify memory |
| WAKEUP | <orapid> | Wake up Oracle process |
| SUSPEND | Suspend execution | |
| RESUME | Resume execution | |
| FLUSH | Flush pending writes to trace file | |
| CLOSE_TRACE | Close trace file | |
| TRACEFILE_NAME | Get name of trace file | |
| LKDEBUG | Invoke global enqueue service debugger | |
| NSDBX | Invoke CGS name-service debugger | |
| -G | <Inst-List | def | all> | Parallel oradebug command prefix |
| -R | <Inst-List | def | all> | Parallel oradebug prefix (return output) |
| SETINST | <instance# .. | all> | Set instance list in double quotes |
| SGATOFILE | <SGA dump dir> | Dump SGA to file; dirname in double quotes |
| DMPCOWSGA | <SGA dump dir> | Dump & map SGA as COW; dirname in double quotes |
| MAPCOWSGA | <SGA dump dir> | Map SGA as COW; dirname in double quotes |
| HANGANALYZE | [level] | Analyze system hang |
| FFBEGIN | Flash Freeze the Instance | |
| FFDEREGISTER | FF deregister instance from cluster | |
| FFTERMINST | Call exit and terminate instance | |
| FFRESUMEINST | Resume the flash frozen instance | |
| FFSTATUS | Flash freeze status of instance | |
| SKDSTTPCS | <ifname> <ofname> | Helps translate PCs to names |
| WATCH | <address> <len> <self|exist|all|target> | Watch a region of memory |
| DELETE | <local|global|target> watchpoint <id> | Delete a watchpoint |
| SHOW | <local|global|target> watchpoints | Show watchpoints |
| CORE | Dump core without crashing process | |
| UNLIMIT | Unlimit the size of the trace file | |
| PROCSTAT | Dump process statistics | |
| CALL | <func> [arg1] ... [argn] | Invoke function with arguments |
Before using ORADEBUG commands, a process must be selected. Depending on the commands to be issued, this can either be the current process or another process
Once a process has been selected, this will be used as the ORADEBUG process until another process is selected
The SETMYPID command selects the current process as the ORADEBUG process
For example
ORADEBUG SETMYPID
ORADEBUG SETMYPID can be used to select the current process to run systemwide commands such as dumps
Do not use ORADEBUG SETMYPID if you intend to use the ORADEBUG SUSPEND command
Before using ORADEBUG commands, a process must be selected. Depending on the commands to be issued, this can either be the current process or another process
Once a process has been selected, this will be used as the ORADEBUG process until another process is selected
The SETORAPID command selects another process using the Oracle PID as the ORADEBUG process
The syntax is
ORADEBUG SETORAPID pid
where pid is the Oracle process ID of the target process For example
ORADEBUG SETORAPID 9
The Oracle process id for a process can be found in V$PROCESS.PID
To obtain the Oracle process ID for a foreground process use
SELECT pid FROM v$process
WHERE addr =
(
SELECT paddr FROM v$session
WHERE sid = DBMS_SUPPORT.MYSID
);
Alternatively, if the DBMS_SUPPORT package is not available use
SELECT pid FROM v$process
WHERE addr =
(
SELECT paddr FROM v$session
WHERE sid =
(
SELECT sid FROM v$mystat WHERE ROWNUM = 1
)
);
To obtain the process ID for a background process e.g. SMON use
SELECT pid FROM v$process
WHERE addr =
(
SELECT paddr FROM v$bgprocess
WHERE name = 'SMON'
);
To obtain the process ID for a dispatcher process e.g. D000 use
SELECT pid FROM v$process
WHERE addr =
(
SELECT paddr FROM v$dispatcher
WHERE name = 'D000'
);
To obtain the process ID for a shared server process e.g. S000 use
SELECT pid FROM v$process
WHERE addr =
(
SELECT paddr FROM v$shared_server
WHERE name = 'S000'
);
To obtain the process ID for a job queue process e.g. job 21 use
SELECT pid FROM v$process
WHERE addr =
(
SELECT paddr FROM v$session
WHERE sid =
(
SELECT sid FROM dba_jobs_running WHERE job = 21
)
);
To obtain the process ID for a parallel execution slave e.g. P000 use
SELECT pid FROM v$px_process
WHERE server_name = 'P000';
Before using ORADEBUG commands, a process must be selected. Depending on the commands to be issued, this can either be the current process or another process
Once a process has been selected, this will be used as the ORADEBUG process until another process is selected
The SETOSPID command selects the another process using the operating system PID as the ORADEBUG process
The syntax is
ORADEBUG SETOSPID pid
where pid is the operating system process ID of the target process For example
ORADEBUG SETOSPID 34345
The operating system process ID is the PID on Unix systems and the thread number on Windows NT/2000 systems
On Unix the PID of interest may have been identified using a top or ps command
This command prints the name of the current trace file e.g.
ORADEBUG TRACEFILE_NAME
For example
/export/home/admin/SS92003/udump/ss92003_ora_14917.trc
This command does not work on Windows 2000 (Oracle 9.2)
In Oracle 8.1.5 and below the maximum size of the trace file is restricted by default. This means that large dumps (LIBRARY_CACHE, BUFFERS) may fail.
To remove the limitation on the size of the trace file use
ORADEBUG UNLIMIT
In Oracle 8.1.6 and above the maximum size of the trace file defaults to UNLIMITED
To flush the current contents of the trace buffer to the trace file use
ORADEBUG FLUSH
To close the current trace file use
ORADEBUG CLOSE_TRACE
This command suspends the current process
First select a process using SETORAPID or SETOSPID
Do not use SETMYPID as the current ORADEBUG process will hang and cannot be resumed even from another ORADEBUG process
For example the command
ORADEBUG SUSPEND
suspends the current process
The command
ORADEBUG RESUME
resumes the current process
While the process is suspended ORADEBUG can be used to take dumps of the current process state e.g. global area, heap, subheaps etc.
This example demonstrates how to take a heap dump during a large (sorting) query
This example requires two sessions, session 1 logged on SYS AS SYSDBA and session 2 which executes the query. In session 2 identify the PID using
SELECT pid FROM v$process
WHERE addr IN
(
SELECT paddr FROM v$session
WHERE sid = dbms_support.mysid
);
In this example the PID was 12
In session 1 set the Oracle PID using
ORADEBUG SETORAPID 12
In session 2 start the query
SELECT ... FROM t1 ORDER BY ....
In session 1 suspend session 2
ORADEBUG SUSPEND
The query in session 2 will be suspended
In session 1 run the heap dump
ORADEBUG DUMP HEAPDUMP 1
The heapdump will show the memory structures allocated for the sort. At this point further dumps e.g. subheap dumps can be taken.
In session 1 resume session 2
ORADEBUG RESUME
The query in session 2 will resume execution
This command resumes the current process
First select a process using SETORAPID or SETOSPID
Do not use SETMYPID as the current ORADEBUG process will hang and cannot be resumed even from another ORADEBUG process
For example the command
ORADEBUG SUSPEND
suspends the current process
The command
ORADEBUG RESUME
resumes the current process
While the process is suspended ORADEBUG can be used to take dumps of the current process state e.g. global area, heap, subheaps etc.
See SUSPEND for an example of use of the SUSPEND and RESUME commands
To wake up a process use
ORADEBUG WAKEUP pid
For example to wake up SMON, first obtain the PID using
SELECT pid FROM v$process
WHERE addr =
(
SELECT paddr FROM v$bgprocess
WHERE name = 'SMON'
);
If the PID is 6 then send a wakeup call using
ORADEBUG WAKEUP 6
To list the dumps available in ORADEBUG use
ORADEBUG DUMPLIST pid
For example in Oracle 9.2 (Windows 2000) this command returns the following
|
To perform a dump use
ORADEBUG DUMP dumpname level
For example for a level 4 dump of the library cache use
ORADEBUG SETMYPID
ORADEBUG DUMP LIBRARY_CACHE 4
To set an event in a process use
ORADEBUG EVENT event TRACE NAME CONTEXT FOREVER, LEVEL level
For example to set event 10046, level 12 in Oracle process 8 use
ORADEBUG SETORAPID 8
ORADEBUG EVENT 10046 TRACE NAME CONTEXT FOREVER, LEVEL 12
To set an event in a session use
ORADEBUG SESSION_EVENT event TRACE NAME CONTEXT FOREVER, LEVEL level
For example
ORADEBUG SESSION_EVENT 10046 TRACE NAME CONTEXT FOREVER, LEVEL 12
To dump the fixed SGA use
ORADEBUG DUMPSGA
To dump an SGA variable use
ORADEBUG DUMPVAR SGA variable_name
e.g.
ORADEBUG DUMPVAR SGA kcbnhb
which returns the number of hash buckets in the buffer cache
The names of SGA variables can be found in X$KSMFSV.KSMFSNAM. Variables in this view are suffixed with an underscore e.g.
kcbnhb_
To peek memory locations use
ORADEBUG PEEK address length
where address can be decimal or hexadecimal and length is in bytes
For example
ORADEBUG PEEK 0x20005F0C 12
returns 12 bytes starting at location 0x20005f0c
To poke memory locations use
ORADEBUG POKE address length value
where address and value can be decimal or hexadecimal and length is in bytes
For Example
ORADEBUG POKE 0x20005F0C 4 0x46495845
ORADEBUG POKE 0x20005F10 4 0x44205349
ORADEBUG POKE 0x20005F14 2 0x5A45
WARNING Do not use the POKE command on a production system
To dump information about operating system shared memory and semaphores configuration use the command
ORADEBUG IPC
This command does not work on Windows NT or Windows 2000 (Oracle 9.2)
On Solaris, similar information can be obtained using the operating system command
ipcs -b
In some versions it is possible to dump the entire SGA to a file
Freeze the instance using
ORADEBUG FFBEGIN
Dump the SGA to a file using
ORADEBUG SGATOFILE directory
Unfreeze the instance using
ORADEBUG FFRESUMEINST
This works in Oracle 9.0.1 and 9.2.0 on Solaris, but fails in both versions in Windows 2000
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/756652/viewspace-242439/ ,如需转载,请注明出处,否则将追究法律责任。