msouth has asked for the wisdom of the Perl Monks concerning the following question:

Here is my file (referred to below as /home/msouth/disconnect.pl):
#!perl -w use strict; use DBI; my $dbh = DBI->connect('dbi:mysql:database=msouth_reg_db;host=redacted +.example.com', 'user', 'pass'); my $rc = $dbh->disconnect; warn "dbh->disconnect returned [$rc]\n"; if (my $ping_val = $dbh->ping) { warn 'here is the thread id ['. $dbh->{mysql_thread_id} ."]\n"; warn "ping returned [$ping_val]\n"; warn "here are Apache-matching keys \%INC:". join "\n", grep {/Apa +che/} keys %INC; } else { warn "ping returned [$ping_val]"; }
if i run this from the command line, it prints what I expect:
dbh->disconnect returned [1] ping returned [] at /home/msouth/disconnect.pl line 14.
If it runs via a "PerlRequire" in my apache conf:
ErrorLog /home/msouth/local/apache/logs/error.log LockFile /home/msouth/local/apache/logs/httpd.lock PidFile /home/msouth/local/apache/logs/httpd.pid # Mod-perl <IfModule mod_perl.c> PerlRequire /home/msouth/disconnect.pl </IfModule> Port 8106
the output upon starting apache is as follows:
dbh->disconnect returned [1] here is the thread id [774516] ping returned [1] here are Apache-matching keys %INC: at /home/msouth/disconnect.pl line + 11.
(new edit with additional information)

I found that, when the disconnect() fails, I can see from mysql's "show processlist" that that the thread with that id is indeed still connected. In my application, I need the threads to disconnect so they will not use resources on the server.



Perl version is 5.8.3, Apache 1.3.33, mod_perl 1.29

Also, I apparently posted this here after not waiting long enough on #perl. Sorry about that.
  • Comment on disconnect, then ping returns true under apache, false from command line, no Apache::DBI around. Why would this be?
  • Select or Download Code

Replies are listed 'Best First'.
Re: disconnect, then ping returns true under apache, false from command line, no Apache::DBI around. Why would this be?
by wazoox (Prior) on Mar 30, 2006 at 10:40 UTC
      Thanks for the advice.

      The complete httpd.conf is included in my question--I reduced it to the nine lines or so in an attempt to eliminate that question.

      I also grepped keys %INC for Apache and found nothing in there in the script--is that sufficient to be sure that Apache::DBI is not the culprit?

      I am working on DBI->trace output now to see if I get any clues out of that output.

      One interesting thing is that I replaced the code with one that explicitly undefs the $dbh, and that seemed to disconnect ok (which would probably be a sufficient workaround). But when I put it in an if branch so I could set a variable to decide whether to try undef()ing or disconnect()ing, both undef() and disconnect() appeared to work.

      I am currently trying to figure out if that is really what is happening, I will post here with results.

      Thanks again for your input.

        The DBI->trace output showed me that mysql_auto_reconnect was on when the script was run by Apache.

        Note that this is true even if you don't have Apache::DBI (which completely overloads disconnect), and even if you don't have mod_perl. DBD::mysql checks for MOD_PERL or GATEWAY_INTERFACE in the env, and if it sees them, turns on mysql_auto_reconnect on the handle when you connect. (perldoc DBD::mysql for details.)

        So in my case I needed to explicitly set  $dbh->{mysql_auto_reconnect} = 0 and then call $dbh->disconnect. Otherwise, when I "verify that it's disconnected" with the ping() call, I actually reconnect first. (The ping() was really just something I was doing to make sure that Apache::DBI hadn't snuck itself back in--a debugging device.)

        Thanks again for help everyone.

        Oh, also, in comparing two DBI->trace outputs I wrote a hack to help diff ignore the differences in memory addresses. Here it is:

        #!perl -w #use like this, if file1 and file2 are two traces of similar db operat +ions: # perl ox2read <file1 >file1scrub # perl ox2read <file2 >file2scrub # diff -c file1scrub file2scrub >mydiff use strict; my @seen_addy = (); while (my $line = <>) { foreach my $sr ( @seen_addy ) { my $search = $sr->[0]; my $replace = $sr->[1]; $line =~ s/$search/$replace/g; } while ($line =~ /(0x\w+)/) { my $search = $1; my $last_replace = @seen_addy ? $seen_addy[$#seen_addy]->[1] : + 'addy001'; my $replace = ++$last_replace; push @seen_addy, [$search, $replace]; $line =~ s/$search/$replace/g; } print $line; }
        It's possible that you are seeing MySQL's auto-reconnect feature. See the DBD::mysql docs for more info on how to disable this.

      ++ but also check your startup.pl

      -derby