当前位置: 代码迷 >> SQL >> 擒获进程在执行的SQL语句
  详细解决方案

擒获进程在执行的SQL语句

热度:95   发布时间:2016-05-05 14:43:01.0
捕获进程在执行的SQL语句

?

?

方法1:?根据服务器processID获取执行的SQL语句

?

?

prompt 根据服务器processID获取执行的SQL语句ACCEPT pid NUMBER prompt '输入服务器的进程编号: ' ;set serveroutput onset verify offdeclare  sqltext varchar2(4000) ;  Cursor c_GetSQLText is      select sql_text      from  V$SQLTEXT_WITH_NEWLINES sqlwn,            ( select s.sid, s.serial#, s.sql_address, s.sql_hash_value             from  v$process p, v$session s             where p.addr = s.paddr             and spid=&pid           ) b     where       sqlwn.address = b.sql_address       and sqlwn.hash_value = b.sql_hash_value     order by piece asc;     begin   dbms_output.enable(1000000);  dbms_output.put_line(' ------------------------------------ ');	  for r_indx in c_GetSQLText loop  	dbms_output.put( r_indx.sql_text);  end loop;	dbms_output.put_line('  ');  dbms_output.put_line(' ------------------------------------ ');end;/ 
?

?

方法2: 跟踪用户当前的session,通过tkproc解析trace文件

?

首先查到在服务器上的processid,然后执行脚本,对该进程进行trace

通过 dbms_system.set_sql_trace_in_sessin(sid, serial#, true/false) 来进行

?

?

-- 首先查到用户的sid, serial#, 通过执行dbms_system.set_sql_trace_in_session(sid, serial#, true/false)来进行对用户session的跟踪。-- 跟踪的结果写在usertrace目录中,通过tkprof可以将trace文件进行转换成用户可以阅读的格式;-- 如果跟踪的是Oracle后台进程,跟踪的结果是写在background_dump_dest中,而不是user_dump_destACCEPT spid NUMBER  prompt '输入服务器的进程编号: ' ;set serveroutput onset verify offdeclare  c_name          INTEGER;  ignore          INTEGER;  Cursor c_getSession is      Select s.sid, s.serial#, s.username     from  v$session s , v$process p     where p.spid = &spid       and p.addr = s.paddr;   trace_dir  varchar2(2000);   instance_name varchar2(2000);begin   	 DBMS_OUTPUT.ENABLE(1000000);   Select value    Into  trace_dir   From v$parameter   Where  name='user_dump_dest';   Select value    Into  instance_name   From v$parameter   Where  name='instance_name';      c_name := DBMS_SQL.OPEN_CURSOR;   for r_indx in c_getSession loop     DBMS_OUTPUT.PUT_LINE( 'User Name : ' || r_indx.username );     DBMS_OUTPUT.PUT_LINE( 'sid : ' || r_indx.sid );     DBMS_OUTPUT.PUT_LINE( 'serial# : ' || r_indx.serial# );        	 DBMS_SQL.parse( c_name,   			    		'begin  sys.dbms_system.set_sql_trace_in_session(  '    			    		|| r_indx.sid || ' , ' || r_indx.serial# || '  , true  ); end;' ,   		 					DBMS_SQL.NATIVE   	 );   	     ignore := DBMS_SQL.execute(c_name);          	     DBMS_OUTPUT.PUT_LINE( ' Trace File Name : '              || trace_dir || '/'              || instance_name || '_ora_' || &spid ||'.trc' );        end loop;   DBMS_SQL.close_cursor(c_name);     end;/
?

?

3. 通过Oracle事件方式进行

? 可以通过Oracle事件10046方式对用户session进行跟踪;

?

自己的?

如果是自己了session,可以执行:

?? Alter Session set events '10046 trace name context forever, level 12'

?

?

? 关闭可以:

?

Alter Session set events '10046 trace name context off';
?

?

?

对其他用户session进行设置

? 通过dbms_system.set_ev来进行;

exec dbms_system.set_ev( sid, serial#, 10046, 级别1/4/8/12, '名字' );

关闭的话,只要把级别设置成0就可以了

?

?

-------------------------------------------

说明:

1. 在跟踪的时候,消耗的时间因素很重要,因此最好把timed_statistics设置成true

? ? 如果是自己的session ,可以 alter session set timed_statistics=true;

? ? 如果是别人的session ,可以 sys.dbms_system.set_bool_param_in_session( sid, serial#, 'timed_statistics', true);

?

2. 可以设置一下trace文件的大小

? dbms_system.set_int_param_in_session( sid, serial#, 'max_dump_file_size', 大小为字节单位 )

?

3. 出来的结果,需要用tkprof进行分析,tkprof的使用可以见这里;

?

?

?

?

?

?

?

?

?

?

?

?

?

?

  相关解决方案