Why increasing ‘max_connections’ in MySQL is just not enough to fix “Too many connections” Error

Updated on September 2, 2017

For the past few days, I started to see this error “Too many connections” in the error log. Generally, the error is due to too many simultaneous connections (means all available connections are in use by other clients) or there might be old connections (sleeping process) that are not allowing new connections to get in.

I started to debug the issue by increasing ‘max_connections‘ variable from 151 (the default) to 200, because the number of connections are controlled by ‘max_connections‘ variable. However, that didn’t solve the issue. I increased it to ‘512’ and again, the error “Too many connection” didn’t stop from occurring in the logs.

mysql error solution

Query the value of max_connections

mysql> show variables like 'max_connections';
+-----------------+-------+
| Variable_name | Value |
+-----------------+-------+
| max_connections | 151 |
+-----------------+-------+
1 row in set (0.07 sec)

Increase the value of max_connections in MySQL

mysql> set global max_connections = 200;

The above command will set max_connections immediately and it will last until ‘mysqld‘ is restarted. To set ‘max_connections‘ permanently, you should edit my.cnf

$ vi /etc/my.cnf

Lookout for [mysqld] section and add the following :

max_connections = 512

You will have to restart the MySQL daemon:

$ /etc/init.d/mysqld restart
mysql> show variables like 'max_connections';
+-----------------+-------+
| Variable_name | Value |
+-----------------+-------+
| max_connections | 512 |
+-----------------+-------+
1 row in set (0.07 sec)

As I told earlier, sometimes increasing the value of ‘max_connections‘ variable is not just enough. The reason, there might be plenty of other MySQL process that are sleeping and yet holding the connection and disallowing new connections. Also the value for ‘max_connections‘ depends upon the amount of RAM available in the system (based on how much RAM being used by each connection). So you can’t keep increasing ‘max_connections‘.

Check the list of sleeping processes in MySQL

mysql> show processlist;
+--------+--------------+-----------+--------+---------+------+-------------+------------------+
| Id | User | Host | db | Command | Time | State | Info |
+--------+--------------+-----------+--------+---------+------+-------------+------------------+
| 597004 | localuser | localhost | NULL | Query | 1 | NULL | show processlist |
| 597051 | localuser | localhost | kdb | Sleep | 800 | | NULL |
| 597062 | localuser | localhost | testdb | Sleep | 710 | | NULL |
| 597063 | localuser | localhost | testdb | Sleep | 70 | | NULL |
| 597067 |localuser | localhost | testdb | Sleep | 61 | | NULL |
| 597083 | localuser | localhost | testdb | Sleep | 522 | | NULL |
| 597084 | localuser | localhost | testdb | Sleep | 5456 | | NULL |
| 597087 | localuser | localhost | testdb | Sleep | 412 | | NULL |
| 597088 | localuser | localhost | testdb | Sleep | 40 | | NULL |
| 597092 | localuser | localhost | testdb | Sleep | 31 | | NULL |
| 597093 | localuser | localhost | testdb | Sleep | 31 | | NULL |
| 597102 | localuser | localhost | testdb | Query | 10 | cleaning up | NULL |
| 597105 | localuser | localhost | testdb | Sleep | 119 | | NULL |
| 597106 | localuser | localhost | testdb | Sleep | 180 | | NULL |
+--------+--------------+-----------+--------+---------+------+-------------+------------------+
14 rows in set (0.40 sec)

Kill MySQL process

mysql > kill 597084;
Query OK, 0 rows affected (0.00 sec)

Why you should set right values for ‘interactive_timeout‘ and ‘wait_timeout

The variable ‘wait_timeout‘ should be set rightly to avoid too many ‘sleep’ process loaded in main memory. More number of sleep process in the RAM will reduce the MySQL performance and will quickly occupying all the available connections (the value set in max_connections). The ‘wait_timeout‘ will allow you to set number of seconds the MySQL server should wait before closing the connection on a non-interactive process.

Set ‘wait_timeout’ in runtime:

mysql > SET GLOBAL wait_timeout=180;

To set ‘wait_timeout‘ permanently:

$ vi /etc/my.cnf

Lookout for [mysqld] section and add the following :

wait_timeout=180;

interactive_timeout : Set the timeout for MySQL command-line sessions such as mysqldump or mysql client tools.

Restart MySQL as below:

$ /etc/init.d/mysqld restart

Set ‘interactive_timeout’ in runtime:

mysql > SET GLOBAL interactive_timeout=200;

To set ‘interactive_timeout’ permanently:

$ vi /etc/my.cnf

Lookout for [mysqld] section and add the following :

interactive_timeout=200;

Restart MySQL as below:

$ /etc/init.d/mysqld restart

Checkout the values of variables as shown below :

mysql> show variables like '%timeout%';
 +----------------------------+-------+
 | Variable_name | Value |
 +----------------------------+-------+
 | connect_timeout | 200 |
 | delayed_insert_timeout | 300 |
 | innodb_lock_wait_timeout | 50 |
 | innodb_rollback_on_timeout | OFF |
 | interactive_timeout | 200 |
 | net_read_timeout | 200 |
 | net_write_timeout | 200|
 | slave_net_timeout | 3600 |
 | table_lock_wait_timeout | 50 |
 | wait_timeout | 180 |
 +----------------------------+-------+
 10 rows in set (0.00 sec)

Note: The ‘wait_timeout‘ will clear the sleep process from RAM and ‘interactive_timeout‘ will affect only the command line sessions. Sometimes you might have to look at setting higher values for ‘connect_timeout‘, ‘net_read_timeout‘ and ‘net_write_timeout‘ (the default values are less) to skip timeout errors for queries that need longer time to execute.

Read this as well : If you are using WordPress, then you might want to hide those ugly database errors in the front end. Learn how to hide “Error Establishing Database Connection” Error in WordPress.

Was this article helpful?

Related Articles

Leave a Comment