Hi,
I am using Apache+mod_perl and Apache::DBI with Oracle connection pooling
feature. I noticed a problem with subroutine connect. Below code checks
database connection:
200: if ($Connected{$Idx} and (!$needping or eval{$Connected{$Idx}->ping})) {
debug(2, "$prefix already connected to '$Idx'");
# Force clean up of handle in case previous transaction failed to
# clean up the handle
&reset_startup_state($Idx);
return (bless $Connected{$Idx}, 'Apache::DBI::db');
}
Due to the oracle connection pooling, some oracle server processes has
terminated the connection, causing httpd process in CLOSE_WAIT state. I did get
this message in error_log when eval{$Connected{$Idx}->ping failed:
DBD::Oracle::db ping failed: ORA-03113: end-of-file on communication channel
Process ID: 28345
Session ID: 3220 Serial number: 504 (DBD ERROR: OCIStmtExecute/Describe) at
/usr/local/lib/perl5/site_perl/5.8.3/Apache/DBI.pm line 200
Below is subsequent code:
213 delete $Connected{$Idx};
214 $Connected{$Idx} = $drh->connect(@args);
215 return undef if !$Connected{$Idx};
After line 214 executes, it doesn't establish a valid new connection. The
httpd process is still in CLOSE_WAIT state.
I wonder this line of code should be changed to 'DBI->connect(@args) if ($@)'.
If ping failed, that means the connection is already closed, $drh may be no
longer valid, will $drh->connect always return a valid new connection? What's
the difference between DBI->connect vs $drh->connect?
Thanks,
- xinhuan