header(Location ) and mysql probelm

Hello All,

My setup is PHP 4.3.3, mysql 3.32 running under RH 9 (2.4.20-8smp).

I have a login script (login.php) that once login credentials have been verified the script sets a few session variables and then redirects the browser to a second page. This second page has a script that queries a mysql database. The problem is this:

If in login.php is have

header ("Location: http://" . $_SERVER['HTTP_HOST'] . dirname($_SERVER['PHP_SELF']) . "/second_page.php");

then in second_page.php I get
mysql_connect(): Can't connect to local MySQL server through socket '/var/lib/mysql/mysql.sock

If I simply reload second_page.php the mysql_query runs as expected

However, if in login.php is have

header ("Refresh: 0; URL=http://" . $_SERVER['HTTP_HOST'] . dirname($_SERVER['PHP_SELF']) . "/second_page.php");

then in second_page.php the mysql_query runs as expected the first time through.

The reason I want to use Location instead of Refresh is because Refresh is not part of the official HTTP specification and causes probelms with some browsers such as Safari.

CODE DETAILS

/* login.php */
ob_start();	// Start output buffering
ini_set("session.cookie_lifetime", 3600);   // set the session cookie to 1 hour
session_start();	// Initialize a session

[SNIP]

session_write_close();	// Make sure session variables are written to disk
ob_end_clean(); 	// Delete the buffer
header ("Location: http://" . $_SERVER['HTTP_HOST'] . dirname($_SERVER['PHP_SELF']) . "/second_page.php");
exit;

/* second_page.php */
ob_start();	// Start output buffering
ini_set("session.cookie_lifetime", 3600);   // set the session cookie to 1 hour
session_start();	// Initialize a session

[SNIP]

$DBC = mysql_connect("$DBHost", "$DBUser", "$DBPasswd");
/* 
Dies the first time through with header("Location ... ") but works after page reoad.
Works first time through with header ("Refresh: 0;  ..)
*/
if($DBC) {
	$DBD =  mysql_select_db($DataBase);
[SNIP]
}

Any ideas? I've been at this for a couple of days ...

Thanks,
Don

    First of all, I would like to compliment you on posing a clear, well formed, well supported question.

    Second of all, that's a weird problem! I would expect the Location redirect to work and the unsupported Refresh redirect to occasionally fail. Hmmm...

    There is a way to see what error MySQL ran into. You can check some logs or put a "die" command after the connection attempt and then echo the actual MySQL error. I'd start there. If you know why MySQL choked, you'll be half way there.

    You might also echo out the values for the variables that MySQL is going to use in the connect string. For example, just before the connect, you might write:

    echo "$DBHost, $DBUser, $DBPasswd";

    just to be certain that those variables are sane. (There's no reason why they shouldn't be... but we're talking about a weird problem here.)

    Also, try commenting out all the session variable assignments. Obviously that won't help you as a solution but it might give you insight into what's causing the MySQL connection to fail.

      Do you ever open a connection to the SQL database in the login.php script?

        First, I would like to thank etully for the kind words and the suggestion to check my mysql logs.

        To answer bradgrafelman yes, login.php does open a mysql_connect() and queries mysql to authenticate the login credentials and grab some info about the user loging in. And this is the start of the problem.

        After some testing I concluded that mysqld dies every time a php script which queries my mysql DB ends. Mysqld dying s independent of sessions, output_buffering, mysql_close() statements or how I call mysql_connect() . This does not happen when I use the mysql commend shell.

        I am noticing the mysqld deaths because second_page.php is trying to open a mysql connection before mysqld has time to complete restarting.

        I spent to many hours trying to fix this but to no avail. Note: the text below deals more with mysql and Linux than PHP.

        Mysqld.log contains this for each page load that has a mysql_connect()

        070330 10:26:48 mysqld restarted
        /usr/libexec/mysqld: ready for connections
        libgcc_s.so.1 must be installed for pthread_cancel to work

        Number of processes running now: 0
        070330 10:26:48 mysqld restarted
        /usr/libexec/mysqld: ready for connections

        Things checked or done to fix it.

        libgcc_s.so.1 is installed and mysqld knows where it is

        ldd /usr/libexec/mysqld
        libdl.so.2 => /lib/libdl.so.2 (0x40027000)
        [SNIP]
        libgcc_s.so.1 => /lib/libgcc_s.so.1 (0x40160000)
        [SNIP]

        ls -laF /lib/libgcc_s
        -rwxr-xr-x 1 root root 30324 Feb 25 2003 /lib/libgcc_s-3.2.2-20030225.so.1

        lrwxrwxrwx 1 root root 28 Mar 30 09:40 /lib/libgcc_s.so.1 -> libgcc_s-3.2.2-20030225.so.1*

        Things that did not prevent mysql from dying:
        Reinstalling libgcc-3.2.2-5.i386.rpm (no newer version available)
        Rebooting
        Adding 'LoadFile /lib/libgcc_s.so.1' to httpd.conf
        Restarting mysqld
        Restarting htppd

        Adding a 0.100 second delay gave mysqld enough time to restart. I went ahead and doubled it to 0.20 seconds since the delay is probably less annoying than the occasional mysql_connect errors

        So in my login.php i have

        usleep(200000);
        header ("Location: http://" . $_SERVER['HTTP_HOST'] . dirname($_SERVER['PHP_SELF']) . "/second_page.php"); 
        

        This is not a fix, but a clunky work around. This server is old, and I plan to replace it this summer, so I'll live with my 0.20 s. of sleep for now unless soemone has a solution.

        Thanks again,
        Don

          Don,

          I have very little experience with sysadminning (is that even a word?) so some of these questions might not even make sense.

          Adding a 0.100 second delay gave mysqld enough time to restart

          Why does it need to "restart"? MySQL (even 3.x) should be able to handle many simultaneous connections. How many connections do you have MySQL set to allow? (I think you configure that in my.conf but I'm not certain).

          There are some awesome MySQL resources out there and, as you said, this isn't really a PHP issue. Some database experts out there should be able to make some suggestions for optimizing your set up. I won't suggest upgrading from 3.x because truthfully, 3.x should more MORE than enough to handle something like this (I used 3.something for many years). Since you clearly have some sysadmin experience, I would suggest looking into some minor MySQL tweaking because even if the sleep work around is working, I'm concerned about what will happen if your site gets any kind of traffic - web pages get simultaneously accessed, it happens, and your site should at least be able to handle 3-4 people banging on the site at the same time and it sounds like that can't happen.

          Also, it's interesting to note that the Location type redirect was many milliseconds faster than the Refresh redirect - I would not have guessed!

            etully wrote:

            Also, it's interesting to note that the Location type redirect was many milliseconds faster than the Refresh redirect - I would not have guessed!

            The explanation might come in the fact that Refresh header probably tells the browser to wait until it has completely finished rendering the page before loading the new page.

            I would higly recommend you visit http://dev.mysql.com and post in either the Forums or the Bugs section and outline your error. You might have success posting this problem in the Database forum of this board, but you definitely have a MySQL installation problem that needs resolving.

              RESOLVED.

              Thanks again Etully and Bradgrafelman . The problem was indeed my my.cnf file. The one I was using was very very minimal. Once I replace my.cnf with a stock file from the RH distro the "libgcc_s.so.1 must be installed for pthread_cancel to work" stopped and header(Location ... ) works. Not sure what in my.cnf was missing. I should read up on mysql configurations ....

              Don

                Write a Reply...