perl-modperl mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Perrin Harkins <>
Subject Re: mod_perl2 DBI handle freshining problem solved "once and for all"...
Date Wed, 01 Feb 2006 21:40:12 GMT
On Wed, 2006-02-01 at 13:22 -0800, Tyler MacDonald wrote:
> 	The point here was that I *wanted* the disconnect() to take place.
> So I made sure Apache::DBI wasn't loaded when disconnect() was called before
> the fork, so that it wouldn't trump my attempt to disconnect the handle
> owned by the parent process.

Apache::DBI doesn't cache handles that you open during startup or
prevent you from calling disconnect on them.  If you have it loaded
correctly and you don't call disconnect on handles opened in startup,
you should see warnings about the handles being DESTROYed without
disconnect.  If you don't see those, it means you are caching the
handles somewhere in your own code.

> 	Perhaps, but how would that explain this paradox:
> 	- After receving this error, calling a disconnect() on the handle
> says "handle already disconnected", yet:

That could mean it was marked inactive when something tried to use the
broken handle and failed (giving you the error).

> 	- After attempting to re-connect() or connect_cache() to the
> database, the *new* handle also exhibits the same screwed up beahviour?

That would require some debugging to figure out.  I would start by
checking to see if the handle is actually new or just the same one for
some reason.

> > 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 issue a rollback on all active connections at the end of every
request.  Everyone who uses transactions at all should do that.

> > Apache::DBI could be changed to rely on connect_cached internals, but it
> > pre-dates connect_cached by years.  It also does important things that
> > connect_cached doesn't do, like automatic rollbacks and voiding
> > disconnect() and not caching handles during startup.  (I didn't want to
> > the disconnect behavior, which is why I stopped using Apache::DBI.)
> 	When I just let a database handle fall off the face of the earth I
> generally get a warning like "DESTROY: issuing ROLLBACK for handle destroyed
> without disconnect". So it seems like a part of that logic is already in the
> new DBI.

Apache::DBI overrides disconnect() to be a no-op, and connect_cached()
doesn't.  (But Apache::DBI doesn't do this during startup.)

> > At this point, I think we don't know what the problem was with your
> > database connections, and I'm not convinced it was a result of an
> > Apache::DBI bug.
> 	I do know that after refactoring my code to not use Apache::DBI at
> all, and not depend on connect_cached() to behave properly, (adding the
> PostConfig and PreConnection handlers to be very paranoid about what happens
> to the handles), the problem has gone away.

That's too many changes at once to draw any conclusions.

> > I do think it would be cool to change the code in Apache::DBI to use
> > connect_cached for some of the caching mechanics, although that would
> > require changes in DBI as well.
> 	Hmm. What changes in DBI?

It currently checks to see if you've loaded Apache::DBI and sends all
connect()/connect_cached() calls there, so that would have to be taken
out to avoid a perpetual feedback loop.

- Perrin

View raw message