[CDBI] Use of _remember_handle in db_Main causes slowdown/huge memory use

David Jack Olrik david at olrik.dk
Wed Oct 19 12:14:33 BST 2005

Hi All,

I have a CDBI/mod_perl setup where I use Perrin's db_Main fix[1] from  
the wiki.

My CDBI modules are also used out side of the mod_perl environment,  
and when doing so __PACKAGE__->_remember_handle('Main') gets called  
every-time db_Main is accessed -> This is the problem!

Ima::DBI->rember_handle uses a Array ref to store the names in like so:

package Ima::DBI;
sub _remember_handle {
     my ($class, $db) = @_;
     my $handles = $class->__Database_Names || [];
     push @$handles, $db;                           <---- BAD!

This will make class variable __Database_Names grow each time db_Main  
is called which is bad.

But what makes it worse, is this:

package Ima::DBI;
sub commit {
     my ($self, @db_names) = @_;
     return grep(!$_, map $_->commit, $self->db_handles(@db_names)) ?  
0 : 1;

So when we call dbi_commit, Ima::DBI will commit one time on the  
first call, two times on the second - and so on - which leads to a  
huge slowdown when creating many objects and committing them.

Under mod_perl this it will not leak/slowdown much, except when we  
loose the connection to the database, and _remember_handle is called  

When the fix is used in a non mod_perl environment, the connection  
pooling is handled by a DBI closure, and not a Ima::DBI closure,  
which means _remember_handle gets called everytime db_Main is called!

Moving __PACKAGE__->_remember_handle('Main'); outside of db_Main  
fixes the problem.

If no-one objects I'll update the wiki...

Perrin: Any comments ?

[1] http://cdbi.dcmanaged.com/wiki/Using_with_mod_perl

Best regards,
David Jack Olrik <david at olrik.dk>             http://david.olrik.dk
GnuPG fingerprint C290 0A4A 0CCC CBA8 2B37 E18D 01D2 F6EF 2E61 9894
["The first rule of Perl club is  You do not talk about Perl club"]

More information about the ClassDBI mailing list