Mike Dameron wrote:
> 
> We have several scripts using Apache::ASP and DBI, which return
> information from an Oracle database.  The problem is that if I run a
> report that taken a long time (not sure how long but over 30 minutes)
> and the connection either times out or I hit the stop button the oracle
> process which gets spawned does not die.  I can see in the process list
> that the oracle process is still tied to a httpd process and continues
> to eat up cpu cycles.
> 

Why would you run a report from a web site that would take
30+ minutes to finish ?  Typical web connection timeouts 
are a few minutes or less ?

I think the real solution is to make your reports fast enough
to run from a web site, like run the real report every night, 
and cache its results in the database for later that you can get
them from the browser instantly.

A problem is that any report that long has the potential 
to read lock your tables, so that if any updates need to 
happen they are locked out.  You web site seems to then
shut down.

One solution is to kill any queries that take too long,
so that your web site is less at risk to these kind of 
untuned database killing queries.  I do this with the 
the below Oracle specific code, run in a cron job.  

Note that I use a class that wraps around DBI, so you 
will have to change some things to make it work for you.

-- Joshua
_________________________________________________________________
Joshua Chamas                           Chamas Enterprises Inc.
NODEWORKS >> free web link monitoring   Huntington Beach, CA  USA 
http://www.nodeworks.com                1-714-625-4051


    $self->Debug("cleaning up locks");
    my $data = $self->DoSQL(<<SQL, 'Fetch');
    -- (
        select s.sid,s.serial#
        from sys.v_\$lock l, sys.v_\$session s
        where l.ctime > $self->{stale_time}
        and l.block != 0
        and (
                l.lmode = 3 or
                l.lmode = 5 or
                l.lmode = 4 or
                l.lmode = 6
                )
        and l.sid = s.sid
        and s.status != 'KILLED'
        order by l.ctime desc
        -- )
SQL
    ;
    return unless $data;

    my($sid, $serial) = @{$data};
    if($SessionKills{"$sid,$serial"}++ >= 3) {
        $self->Critical("killing session $sid,$serial, give up");
    }

    my $rv = $self->DoSQL("alter system kill session '$sid,$serial'") || 0;
    $self->Log("killing stale session $sid: $rv\n");
    $self->Commit();

Reply via email to