Beefy Boxes and Bandwidth Generously Provided by pair Networks
"be consistent"
 
PerlMonks  

mod_perl breaks MySQL connectivity...

by Anonymous Monk
on May 22, 2001 at 08:54 UTC ( [id://82163]=perlquestion: print w/replies, xml ) Need Help??

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

I have recently installed mod_perl on my development server to assess the performance benefits often claimed of it. For the most part I have been absolutely stunned by the massive speed increases I have witnessed through its usage. However, I have come up against a major barrier: I can't connect to any MySQL DB server(s) from scripts running under mod_perl. If I disable mod_perl, then these same scripts work fine. I am at a loss as to what's going wrong. I have discussed this on various mailing lists without resolving the problem. Now, I throw myself on the mercy of our esteemed monks - in the hope that I can get these scripts working.

Server Configuration:

  • Windows 2000
  • Apache/1.3.19 (Win32)
  • mod_perl/1.24_01
  • MySql 3.23.38-nt
  • Perl 5.6

The DB works fine: I can connect via MySQLAdmin; I can connect via PHP4; I can connect via CGI; I cannot connect via mod_perl.

The relevant section of "httpd.config" is as follows:

LoadModule perl_module modules/ApacheModulePerl <Files *.pl> SetHandler perl-script PerlHandler Apache::Registry Options ExecCGI PerlSendHeader On </Files>

A minimalist Perl program that demonstrates my problem is as follows:

#!perl print ("Content-type: text/html\n\n"); use strict; use vars qw($query $dsn $driver $db_username $db_password $dbh); require 5.006; $| = 1; ($0 =~ m,(.*)/[^/]+,) && unshift (@INC, "$1"); +($0 =~ m,(.*)\\[^\\]+,) && unshift (@INC, "$1"); use CGI qw(:standard); use CGI::Carp 'fatalsToBrowser'; $CGI::POST_MAX = (1024 * 0); $CGI::DISABLE_UPLOADS = 1; $query = new CGI; use DBI(); $driver = "mysql"; $dsn = "DBI:$driver:database=shapeshifter;host=localhost;port=80"; $db_username = "nobody"; $db_password = ""; warn "Before DBI->connect(): [$$]"; $dbh = DBI->connect($dsn, $db_username, $db_password) or die sprintf " +Error: %s.\n", DBI->errstr; warn "After DBI->connect() [$$]"; my $sth = $dbh->prepare("SELECT * FROM frontpage"); $sth->execute(); while (my $ref = $sth->fetchrow_hashref()) { print qq~Found a row: id = $ref->{'serial_number'}, name = $ref->{ +'position'}<BR>~; } $sth->finish(); $dbh->disconnect(); if ($ENV{'MOD_PERL'}) { print "Mod_perl is installed on this server: $ENV{'MOD_PERL'}<br>< +br>\n"; } else { print "Mod_perl is not installed on this server<br><br>\n"; }

The relevant output from "error.log" reads:

[Tue May 22 05:19:57 2001] nul: Before DBI->connect(): [2576] at e:/pa +d/htdocs/internet/system/db_test.pl line 20.<BR> [Tue May 22 05:19:58 2001] nul: DBI->connect failed: Can't connect to +MySQL server on 'localhost' (10061) at e:/pad/htdocs/internet/system/ +db_test.pl line 21<BR> [Tue May 22 05:19:58 2001] [error] Error: Can't connect to MySQL serve +r on 'localhost' (10061).

Can anyone tell me what's going wrong, before I tear out my few remaining strands of hair and go in search of a gun and belltower?

Thanks in advance

Edit: chipmunk 2001-05-22

Replies are listed 'Best First'.
(tye)Re: mod_perl breaks MySQL connectivity...
by tye (Sage) on May 22, 2001 at 09:49 UTC

    Well, I can tell you that "10061" is "Connection refused" under WinSock (the Windows Socket layer, a.k.a. TCP/IP for Win32). Based on "host=localhost;port=80", this almost always means that there is nothing that is listening to port 80 of localhost. Port 80 is usually used by the web server. Is MySQL really using that port number on the same computer as your web server is running on (that just seems strange to me)?

    Mostly FYI, a common misunderstanding about TCP/IP is that people don't realize that a server process can listen not just to a port number but also to a specific combination of address and port number. So a common mistake with TCP/IP servers is to have the server specify which address it is to be contacted at rather than specifying only the port number (that is, specifying an address of INADDR_ANY). So it is possible to have a server process that can be contacted when you use its name (or IP address) but that will give "connection refused" if you try to access it as "localhost".

    I don't see any smoking guns for the particular error that you are getting, but I'll mention a couple more things that seem strange.

    ($0 =~ m,(.*)/[^/]+,) && unshift (@INC, "$1"); ($0 =~ m,(.*)\\[^\\]+,) && unshift (@INC, "$1");
    since that code happens at run time, it won't have any effect on any subsequent use statements (which happen at compile time). It could change where subsequent require statements look for modules, but that code is followed only by use statements, not require statements, so it is useless in this snippet.

    Also, one difference between mod_perl and the other situations you mentioned is that the run-time pass happens over and over via some trickery about putting all of your code inside of a sub. So this probably means that in mod_perl the above code actually gets run over and over again and @INC gets very, very full.

    So you should really but that code inside a BEGIN block.

    I thought one of the big points of mod_perl was that you could intelligently cache and reuse your DBI connections, saving lots of time-consuming reconnecting for every single page hit. I suggest you look into an appropriate module for doing that.

            - tye (but my friends call me "Tye")
      I believe you need to install and enable Apache::DBI for DBI to maintain database connections.

      -Lee

      "To be civilized is to deny one's nature."

        Just to expand a little on this, Apache::DBI is extremely easy to use. Download and install it, then add

        PerlModule Apache::DBI

        to the relevant section of your httpd.conf (the one you referenced above). Apache::DBI should now be handling all your connections.

        Assuming you've taken care of any variable scoping issues, you should have persistent connections. At least, this is how everything worked on linux for me.

Re: mod_perl breaks MySQL connectivity...
by Odud (Pilgrim) on May 22, 2001 at 18:21 UTC
    port 80 for MySQL looks odd, as has already been pointed out, can you confirm that you don't change the script between runs with and without mod_perl? You also could get some useful results from invoking the script from the command line on the server - you supply any parameters after the invocation in the form
    param1=value1
    param2=value2
    ...
    and end with CTRL+D
    This will prove at least that your script is correct - if it is then you shouldn't really have any problems with mod_perl. A tip: don't try to do the clever persistence and reloading stuff until the basics are working.
    I'm sure you know already but there is a lot of good stuff at Stas's Home Pages.
      This is now solved - changing "localhost" to "127.0.0.1" did the trick. I'd be interested in learning why as I thought the two were interchangeable.

      Thanks to everyone who responded for your help and advice. I really appreciate it.

       

      In theory, there is no difference between theory and practise.  But in practise, there is.
       
      Jonathan M. Hollin
      Digital-Word.com

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://82163]
Approved by root
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others rifling through the Monastery: (4)
As of 2024-04-19 03:20 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found