I am having a problem maintaining a dbh handle between database
calls. If I disconnect immediately after every query _WITHIN_ the
same routine which makes the query, there is no leak, but if I store
the $dbh obtained from connect and then disconnect outside of the
routine, I leak memory under mod_perl. I would very much appreciate
any help on this.
Here are the steps to demonstrate the leak:
1) Start httpd with mod_perl, keep number of processes low (5-10
should do) that
will show the results fastest.
2) Run
ps -ely | grep http | sort
to monitor process sizes
3) From (preferably) another machine run
/path/to/apache/bin/ab -n 5000 -c 50
http://host.with.test.install/mod_perl/test.cgi
4) Watch the memory usage grow as you run and repeat 3)
Here is the (pared-down) program which leaks. If I uncomment the
'endConnection();' line in the getall function, there is no leak, but
then I lose the ability to reuse the handle in the unabridged program.
#!/usr/local/bin/perl
use strict;
use DBI;
use vars qw( $gDBH);
sub endConnection
{
if ($gDBH eq 0) {
} else {
$gDBH->disconnect();
$gDBH = 0;
}
}
sub getConnection
{
if ($gDBH) { return $gDBH; }
my $dbh;
$dbh = DBI->connect( "id", "user", "pwd", 'Oracle' );
$gDBH = $dbh;
return $dbh;
}
sub getall
{
my ($sql) = @_;
my $dbh = getConnection();
my $cursor = $dbh->prepare( $sql);
my $rlt = $cursor->execute();
my $rows = $cursor->fetchall_arrayref();
$cursor->finish();
#endConnection();
return $rows;
}
sub main
{
my $sql = "select to_char(SYSDATE,'YYYY MM DD HH24 MI SS') from dual";
my $rows = getall( $sql);
endConnection();
my $row = $rows->[0];
print "time: $row->[0]<br>\n";
}
$ENV{'ORACLE_HOME'} = "/users/oracle/product/8.0.5";
print "Content-Type: text/html\n\n";
print "hello\n";
&main();