4

I have been recently getting these errors on my server:

mysql_connect() [function.mysql-connect ]: 
   Can't connect to MySQL server on 'xxx.xxx.xxx.xxx' (4)

I don't think this is a credentials issue since the username, password, host IP, and database name are all read from a flat file config and stored in a PHP constant. Plus my error log tells me that the credentials being used are actually the ones in the config.

I tried to google this up and one points me to a max_connections issue. This site is still in beta and the number of concurrent users does not exceed 10. I looked up the value of max_connections and it is at 2048

The MySQL version is 5.0.91 and the server is Gentoo Linux (its what the version_comment says). Socket file is at /var/run/mysqld/mysqld.sock and port is 3306

What's really bugging me is that this error seems intermittent. I really can't catch it when I am trying to reproduce it. Somebody said from one site that the error index (4) means interrupted systems calls.

Does this mean that I can dismiss the error as a fault in my web host and not my PHP script?

Rolando Cruz
  • 203
  • 2
  • 8

3 Answers3

1

Try to see if you're not exeeding the max open file limit typing dmesg and watching for the "Too many open files" error.

If you're exeeding it, you'll have to increase the limits fixed by the system by changing the /etc/security/limits.conf with this statement :


mysql           soft    nofile          2048
mysql           hard    nofile          4096

Where 2048 and 4096 are the maximum number of files the user "mysql" can open. (This includes all file descriptors such as sockets)

DrGkill
  • 976
  • 6
  • 8
1

If your connection string ref's server node name and requires DNS, make sure it is not intermediate slow DNS resolve causing timeout in connection attempt. Use localhost if that is appropriate. Run local DNS if appropriate. Shortcircuit in LMHOSTS file if appropriate. Eliminate need for DNS totally and if appropriate, specify the IP address. Whatever needed to not be dependent on external sometimes slow DNS lookup of the server name in your connection string.

Sometimes nothing wrong with connection string; sometimes, DNS resolve is intermittently too slow. This could be one cause of intermittent connect problems.

Example: suppose you have cloud instance hosting both mysql and apache, but sometimes you run site on local devo machine. So in your connection string, you use full server node name, so the site 'works' either from deployment site or your devo machine. It might be the case that it never fails on your devo machine(because your devo machine DNS is always shiny) but you get intermittent connection problems on the deployed site (because even though the mysql instance is co-located, your connection string still needs to be DNS resolved back to itself, but the DNS on your cloud instance is sometimes not as shiny. A little maddening, because in the deployed instance, the mysql instance is actually local. But not actually even the point-- the point really is, the difference between your devo machine DNS response time under all load conditions, vs same on the cloud instance. So, make it as easy as possible on the cloud instance. The error won't be "DNS was too slow" even though that is the underlying cause.

frediano
  • 11
  • 1
0

You may dig down in further by utilizing the mysql_error() and mysql_errno()-functions, but from what I can tell, your assumptions are right.

As a short bugfix (which I usually implement in my webapplications) is a reconnect with logging after two seconds:

$i = 0;
if ($i < 3 && ($db = mysql_connect(...)) == false) {
    trigger_error('Could not connect to ...', E_USER_WARNING);
    $i++;
    sleep(2);
}
if (!$db)
    die('Could not connect to ... for 3 times with a 2 second dely - giving up');

As the site is low-traffic, you might consider running a tcpdump on the server to a file and configure your php script to mail you a warning if a connection fails. Copy over the tcpdump-file to your local box and analyse the connection failure via wireshark.

You should also check the mysql-daemon logs and the system logs on your system around the time of failure for anomalies.

Be aware, that logging your traffic will log all contents of the traffic including passwords and other sensitive information and thus may be violating company policies or laws. You should wipe the tcpdump-file after deactivating the logging to not let any sensitive information left on the server and transfer the files via ssh or any other appropriate encrypted connection.

Lars
  • 486
  • 5
  • 21