PHP to MySQL connection: wait until a connection is available, instead of throwing "max_user_connections exceeded" error?

StackOverflow https://stackoverflow.com/questions/23294275

Question

MySQL has a feature that enforces a maximum number of connections, max_user_connections.

When connecting from PHP (and other languages), in the event you exceed that number, my understanding is that your connection will fail with an error stating that you have exceeded the maximum number of connections. Correct?

My preference would be to instead have the connect call wait (up to some timeout limit) for a connection to become available. However, I have not been able to determine a way to do this from reading through the MySQL docs and searching the web.

My concern is that, in the event we have a flood of traffic to our web app that resulted in a large number of concurrent MySQL connection attempts, some of our users scripts will end with an error. Naturally, we could modify the calling code to try to re-connect up to a certain number of times, but it would much cleaner if we could modify the connection attempt itself to handle this, instead of having to wrap every "connect" call in a loop. Additionally, a loop would not result in a real FIFO queue, because each individual calling thread would wait a small period of time and try again, and whether it got a connection would depend on whether, at that particular moment, a connection was available. It would then wait again, and while it was waiting a connection might open and a different thread "further back in line" might grab it.

So, when using any of the PHP APIs to connect to MySQL, is there a way to attempt the connection in "wait until a connection is available" fashion?

Was it helpful?

Solution

MySQL doesn't have any feature to do what you're describing. That is, MySQL has no FIFO (queue) of connections when you hit max_connections. All connections get an error if they can't get connected immediately.

The closest related thing built into MySQL is the config variable back_log, which only configures the limit on the number of outstanding connections. That is, the main MySQL thread takes a small amount of time to check for incoming connections, and these stack up in the listen queue, which is before the socket even completes and before MySQL determines if we've got more than max_connections threads. In fact, you could get a bunch of outstanding connections in the listen queue even if the server is currently far below max_connections threads.

http://dev.mysql.com/doc/refman/5.6/en/server-system-variables.html#sysvar_back_log

Another option is to add HA-Proxy into the mix, because HA-Proxy does have provide queue feature. Here's a blog that explains this more: http://flavio.tordini.org/a-more-stable-mysql-with-haproxy

Frankly, most sites just increase max_connections until it can handle your typical spikes in traffic, and from there just try to optimize database activity, so connections are short in duration and therefore you have good throughput. It also helps to code your application to connect as late as possible and disconnect as promptly as possible once all queries are done.

If you have an atypical spike in traffic that exceeds max_connections, then your application will receive an error indicating that. You should code your app to handle such errors gracefully. That is, display as nicely as you can a message like "We're sorry, our load is too great to handle your request at the moment, please try back in a minute." That's at least better than an abrupt white screen, or a stack trace or something.

OTHER TIPS

Try add below php code in all php page in footer:

  mysql_close();

Normally your error message is the mysql connection without close and keep hold the connections in server side. However, it just my stupid coding error in long time ago. If close the mysql connection also cannot fix your problem. I think you need to login to server to change some setting of php.ini to increase the connection user value. I wish my answer can help you to resolve problem.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top