mod_perl2 DBI handle freshining problem solved "once and for all"...

mod_perl2 DBI handle freshining problem solved "once and for all"...

am 31.01.2006 22:23:12 von Tyler

Apache::DBI and DBI's connect_cached both claim to keep your database
handles fresh and happy, but I've had numerous problems trying to get either
of them to work properly. If a database connection is dropped, sometimes I'd
have to refresh the page two or three times before the "internal server
error" goes away and my webpages are happily reconnected to the database
again.

Part of the problem seems to be that disconnecting a database handle doesn't
always remove it from {CachedKids}. At least, in the case where DBI thinks
it's already disconnected, it doesnt bother removing it.

Anyways, here's what I've done to solve the problem (i'm using postgres):

- always use connect_cached, don't use Apache::DBI

- use this as my PerlPostConfigHandler:

sub PostConfig {
my $drh = DBI->driver("Pg");
my $n = 0;
while(my($k, $v) = each(%{$drh->{CachedKids}})) {
eval { $v->disconnect if $v->{Active} };
delete $drh->{CachedKids}->{$k};
$n++;
}
warn "$$: Cleared $n postgresql database handles before forking.\n" if $n;
return DECLINE_CMD;
}

- use this as my PerlPreConnectionHandler:

sub DisconnectDead {
my $drh = DBI->driver("Pg");
my $n = 0;
while(my($k, $v) = each(%{$drh->{CachedKids}})) {
if(! eval { $v->ping }) {
eval { $v->disconnect if $v->{Active} };
delete $drh->{CachedKids}->{$k};
$n++;
}
}
warn "$$: Cleared $n stale postgresql database handle(s).\n" if $n;
return DECLINE_CMD;
}


This seems reasonably robust, after doing something like:

# ps ax | grep "postmaster: pmx" | grep -v grep | awk '{print $1}' | xargs kill

The first reload is a bit sluggish, but always works.

Cheers,
Tyler

Re: mod_perl2 DBI handle freshining problem solved "once and

am 02.02.2006 01:30:08 von GalbreathM

--=__Part183AB780.2__=
Content-Type: text/plain; charset=US-ASCII
Content-Transfer-Encoding: quoted-printable

and...?
=20
]:-)

>>> Tyler MacDonald tyler@yi.org> 01-Feb-06 17:06 PM >>

Yeah, I ditched Apache::DBI early in diagnosing this problem. Then I
wrote that hack to solve it, which is what has started this whole thread. =
I
was happy just posting the hack and leaving it at that, but you guys keep
egging me on ;-)



--=__Part183AB780.2__=--

Re: mod_perl2 DBI handle freshining problem solved "once and

am 02.02.2006 08:11:24 von michael.peppler

> > > For this purpose, "connected" and "pingable" are the same thing.
> >
> > Yes and no. If you can't ping the server, but the TCP socket is
> > still open, that means you essentially have this TCP connection to the
> > server that's not being used, in an open state, for the rest of the
lifetime
> > of your apache server instance. This could be a Bad Thing, say, if it's
in
> > mid-transaction, keeping a table lock open...

> Sorry, but this sounds like total conjecture to me. You have to expect
> certain basic things to work, and one of them is that a connection which
> can't be ping'ed is not holding a table lock. If it is, this is a much
> lower-level bug than DBI should try to deal with.

I'll add one more thing - for some drivers a call to $dbh->ping() will
generate a *new* connection *if* the driver thinks that the $dbh is
currently active (ie has an active $sth) - DBD::Sybase in particular, but I
suspect that other drivers that don't support multiple active statements on
a single physical connection will have the same behavior.

Michael


This message and any attachments (the "message") is
intended solely for the addressees and is confidential.
If you receive this message in error, please delete it and
immediately notify the sender. Any use not in accord with
its purpose, any dissemination or disclosure, either whole
or partial, is prohibited except formal approval. The internet
can not guarantee the integrity of this message.
BNP PARIBAS (and its subsidiaries) shall (will) not
therefore be liable for the message if modified.

---------------------------------------------

Ce message et toutes les pieces jointes (ci-apres le
"message") sont etablis a l'intention exclusive de ses
destinataires et sont confidentiels. Si vous recevez ce
message par erreur, merci de le detruire et d'en avertir
immediatement l'expediteur. Toute utilisation de ce
message non conforme a sa destination, toute diffusion
ou toute publication, totale ou partielle, est interdite, sauf
autorisation expresse. L'internet ne permettant pas
d'assurer l'integrite de ce message, BNP PARIBAS (et ses
filiales) decline(nt) toute responsabilite au titre de ce
message, dans l'hypothese ou il aurait ete modifie.