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

Perrin Harkins perrin at elem.com
Wed Oct 19 19:58:26 BST 2005


On Wed, 2005-10-19 at 11:35 -0500, Peter Speltz wrote:
> Does anyone know whatever became of the Ima::DBI patch for this?  If i
> remember Perrin posted a couple  on the old list.

I've evolved it a bit.  I have a version that I need up put on CPAN
which allows you to specify your own custom connection handler, but for
now you are welcome to use this quick change.  It's just a modification
of the _mk_db_closure sub in Ima::DBI.  With this change, it is not
necessary to override db_Main.

sub _mk_db_closure {
        my ($class, $dsn, $user, $pass, $attr) = @_;
        $attr ||= {};

        my $dbh;
        my $process_id = $$;
        return sub {
                # set the PID in a private cache key to prevent us
                # from sharing one with the parent after fork.  This
                # is better than disconnecting the existing $dbh since
                # the parent may still need the connection open.  Note
                # that forking code also needs to set InactiveDestroy
                # on all open handles in the child or the connection
                # will be broken during DESTROY.
                $attr->{private_cache_key_pid} = $$;

                # reopen if this is a new process or if the connection
                # is bad
                if ($process_id != $$ or
                    not ($dbh && $dbh->FETCH('Active') && $dbh->ping)) {
                    $dbh = DBI->connect_cached($dsn, $user, $pass,
$attr);
                    $process_id = $$;
                }
                return $dbh;
        };

}

If you use transactions, you also need a rollback handler.  I use this:
sub cleanup ($$) {
    my $class = shift;
    my $dbh = $class->db_Main();
    if (!$dbh->{AutoCommit}) {
        debug("Issuing automatic rollback in cleanup handler for $dbh");
        $class->dbi_rollback();
        $dbh->{AutoCommit} = 1;
    }
}

I call this with the following in httpd.conf:
PerlCleanupHandler Arcos::DB->cleanup

Sam Tregar helped track down some problems in my original patch, which
were showing up when using this in a custom forking perl daemon.  You
can ignore the note about InactiveDestroy when running under mod_perl,
since the parent process never uses the database connection after the
fork.

Regarding the _remember_handle thing, the change makes sense, and I
expect this would be an issue under mod_perl as well, since it will call
that once at the beginning of every request.  Go ahead and update the
wiki.  I wasn't actually using _remember_handle in my code, but was
overriding dbi_commit and dbi_rollback instead, as shown in the older
version on the (original) wiki.

- Perrin





More information about the ClassDBI mailing list