skip to main | skip to sidebar

Search Oracle Blogs

List of Blogs maintained by Paweł Barut.


Wednesday, March 28, 2007

Monitor progress of long running processes

This time I want to share how I use v$session_longops to monitor Oracle long running queries but also how to create your own entries in this view. When monitoring long lasting operation I'm interested what is running now, and what was finished lately. For this purposes I use query:
SELECT sid,
 serial#,
 opname,
 target_desc,
 percent,
 sofar,
 totalwork,
 to_char(start_time, 'hh24:mi:ss') start_time,
 to_char(efin, 'hh24:mi:ss') estimate_fin,
 case when sofar  totalwork and last_update_time < sysdate-1/10000 then '*' else null end broken FROM (SELECT sid, serial#, opname, target_desc, sofar, totalwork, to_char(CASE WHEN totalwork = 0 THEN 1 ELSE sofar / totalwork END *100, '990') percent, start_time, last_update_time, start_time +((elapsed_seconds + time_remaining) / 86400) efin FROM v$session_longops ORDER BY CASE WHEN sofar = totalwork THEN 1 ELSE 0 END, efin DESC) WHERE sofar  totalwork or rownum <= 20;
It lists all currently running operations and up to twenty lately finished. The most important columns are estimate_finish – it predicts time of process end, and broken – if contains star (*) it is very possible that process was terminated or hung. Constant 1/10000 (about 8 seconds) in comparison
efin < sysdate-1/10000
is to avoid false alerts. If single step of yours process takes more then 8 seconds than you should alter this value to meet your needs. You can find more information on v$session_longops view in Oracle documentation.
Sample output:

Lets take a look how to write your own entries to long operations view. As a samle I'll just use simple loop that for each record in ALL_OBJECTS process will sleep for 0.1 second:
declare
 v_rindex pls_integer;
 v_slno pls_integer;
begin
 v_rindex := dbms_application_info.set_session_longops_nohint;
 for r_qry in (select t.*, rownum rn, count(*) over () cnt 
 from ALL_OBJECTS t ) loop
 dbms_application_info.set_session_longops
 ( rindex => v_rindex,
 slno => v_slno,
 op_name => 'ALL_OBJECTS processing',
 target => 0,
 target_desc => 'ALL_OBJECTS',
 context => 0,
 sofar => r_qry.rn,
 totalwork => r_qry.cnt,
 units => 'loops'
 );
 dbms_lock.sleep(0.1);
 end loop;
end;
So what is important here:
  • rindex – for first call it must be ste to dbms_application_info.set_session_longops_nohint – it means add new row to v$session_longops view
  • rownum is used to get row number; it is passed to sofar parameter
  • analytical function (count(*) over () cnt) is used to calculate all rows (steps) in that process; it is passed to totalwork parameter
  • rindex, slno – should be assigned always to the same variable; it is needed to pass information about row that should be changed
Additionaly you can add when others handler to set progress to 100%, but you do have to do that. Broken flag described above should work fine, and you know if process ended normally or with errors. Full specification of dbms_application_info.set_session_longops

Paweł

1 comment:

Dave said...

Thx! Very Usefull

05 June, 2012 00:07

Post a Comment

Subscribe to: Post Comments (Atom)
 

AltStyle によって変換されたページ (->オリジナル) /