Perrin Harkins <[EMAIL PROTECTED]> wrote: > > 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.
I completely agree. :) > 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. I completely disagree. Here's some more conjecture: What if you can't ping the connection because of a temporary TCP/IP problem (eg; somebody tripping over the network cable)... the driver's ping timeout could easily expire before the TCP/IP stack's timeout expires, the cable coule be plugged back in, and then TCP/IP's happy, DBI experienced a ping timeout, but the connection is not technically "closed". If this can happen on my SSH sessions when my daughter yanks on my network cable, it could certainly happen on a database driver. And here's some more conjecture: What if the ping just times out because the server is really, really busy? > If it is, this is a much lower-level bug than DBI should try to deal with. If DBI doesn't plan on using a cached database handle anymore, it should at least disconnect() it and remove it's dangling reference from CachedKids. I don't know if it does an explicit disconnect() itself in this case, but I do know the handle reference (which is essentally garbage at this point) is left laying around. > I issue a rollback on all active connections at the end of every request. > Everyone who uses transactions at all should do that. I wrote DBIx::Transaction specifically so I wouldn't have to worry about that anymore. ;-) It's so much easier just to $dbh->transaction(sub { ... return $do_i_want_to_commit ? 1 : 0; }); especially now that I can nest them arbitrarily deep. > > 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.) 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 ;-) > > 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. They were done one at a time. To the best of my memory: - Not using Apache::DBI came first. That made it so that after about a dozen refreshes my database handles were OK again. - PreConnection handler came next, along with wrapping my disconnect() call in an eval{}. That brought it down to 2 or 3 refreshes. - The PostConfig handler came next, along with deleting the dangling references from CachedKids. I'm not sure if the CachedKids things helped, but it certainly doesn't do any harm so I left it in. So these last two changes may need to be diagnosed further. > 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. Aaaah. :) - Tyler