On Thu, 2004-05-27 at 21:34, Mike Blazer wrote:
> It's hard to extract the part of the code because my configs look wild
> :)

Holy cow, this is a lot of code.  The simplest thing I can think of to
see what's going on is to turn on Apache::DBI debugging and then watch
your error_log.  If you see a bunch of stuff about "skipping connection
cache during server startup" that's good.  You could still be foiling it
by stashing database handles in globals or closures though.

>   # here's a workaround to override DBI methods with Apache::DBI ones
>   {
>   package DBI;
>   $connect_via = "Apache::DBI::connect";
>   }

Ack!  Don't do that!  Just load Apache::DBI at the top of your
httpd.conf like it says to in the docs.

> because of the 2nd pass. Dunno, may be there is some problem with this
> 2nd pass...

It's the standard "server starts twice on startup" issue.  It's in the
docs.

> OK, and after that the whole stuff starts, few different PerlHandler
> modules that use the same dbh like this
> 
> sub handler {
> ...
> 
> $Counter::db and $Counter::db->reconnect;
> 
> unless ($Counter::db) {
>   $Counter::db ||= MySQL::Tools->dbopen( @Counter::INI::DBopendata )
>      or croak MySQL::Tools->errstr;
> }

That looks like a problem to me.  Don't put database handles in
globals.  You will regret it.  If any code like this gets run outside of
a sub in a module that is use()ed during startup, you would get sharing
of handles between processes.

> MySQL::Tools->dbopen returns $db and $db->dbh is DBI::db object (or
> Apache::DBI::db in case it overrides DBI)
> 
> dbopen() finishes with 
> 
>   $self->reconnect or return;
> 
>   $self;
> }
> 
> and reconnect() actually opens the connection:
> 
> sub reconnect {
>  my $self = shift;
>   my $old_dbh = $self->{dbh} ? "$self->{dbh}" : "";

Okay, so it looks like you are stashing database handles in this object
too, which could also be the problem if this object ever gets put into a
global or a closure.

I'm not sure why you need all this code just to connect to the
database.  Usually you only need a few lines to deal with the config and
the rest is left to Apache::DBI.

>   $self->{"dbh"} and $self->{"dbh"}->disconnect;
> in 'reconnect' sub makes nothing in case of Apache::DBI and is supposed
> to do reconnection if called in non-mod_perl environment. It's actually
> added for some persistency, to mean 'reconnect' even not under mod_perl

I'm not following this, but if you want database persistence outside of
mod_perl, use DBI->connect_cached().  It's safe under mod_perl too,
since it will just delegate to Apache::DBI if Apache::DBI is loaded. 

> END { eval{ $Counter::db->dbclose } if $Counter::db }

Those don't run until the server shuts down.

> To remind the problem - few first Apache childs manage to connect the
> same mysql thread at startup. Then they all fail, reconnect and live
> happily ever after :)

Actually, I would say that the apache parent connects to MySQL, you
store that connection somewhere, and then apache forks and multiple
children end up with that same connection.

- Perrin


-- 
Report problems: http://perl.apache.org/bugs/
Mail list info: http://perl.apache.org/maillist/modperl.html
List etiquette: http://perl.apache.org/maillist/email-etiquette.html

Reply via email to