0%

连接Mysql时出现too many connections的一些解决办法

通过Navicat客户端连接Mysql数据库时,出现too many connections的提示,可以进行如下操作

登录mysql数据库

1
2
3
4
5
6
7
8
9
10
11
12
13
# mysql -u root -p
Enter password:
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 2965
Server version: 5.7.18 MySQL Community Server (GPL)

Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

查看连接数

1
2
3
4
5
6
7
8
mysql> show processlist;
+------+------+---------------------+--------------+---------+------+----------+------------------+
| Id | User | Host | db | Command | Time | State | Info |
+------+------+---------------------+--------------+---------+------+----------+------------------+
| 2821 | root | 192.168.1.124:58526 | testdb | Sleep | 7180 | | NULL |
| 2822 | root | 192.168.1.124:58527 | testdb | Sleep | 7180 | | NULL |
| 2840 | root | 192.168.1.124:58741 | testdb | Sleep | 5790 | | NULL |
| 2841 | root | 192.168.1.124:58742 | testdb | Sleep | 5820 | | NULL |

将会发现有很多连接是处于Sleep状态的,这些连接是暂时没有用的,可以删除掉。如何删除请继续往下看。

查看最大连接数

1
2
3
4
5
6
7
mysql> show variables like "max_connections";
+-----------------+-------+
| Variable_name | Value |
+-----------------+-------+
| max_connections | 151 |
+-----------------+-------+
1 row in set (0.01 sec)

当processlist的数量大于查询到的max_connections时,就会出现too many connections的提示信息。

修改最大连接数

1
set GLOBAL max_connections=1000;

这不是一劳永逸的方法,应该要让它自动杀死那些sleep的进程。

查看关闭一个连接的等待时间,并修改

1
2
show global variables like 'wait_timeout';
set global wait_timeout=300;

修改这个数值,这里可以随意,最好控制在几分钟内。

其他待验证

set global interactive_timeout=500;
修改这个数值,表示mysql在关闭一个连接之前要等待的秒数,至此可以让mysql自动关闭那些没用的连接,但要注意的是,正在使用的连接到了时间也会被关闭,因此这个时间值要合适

批量kill之前没用的sleep连接,在网上搜索的方法对我都不奏效,因此只好使用最笨的办法,一个一个kill

select concat(‘KILL ‘,id,’;’) from information_schema.processlist where user=’root’;

先把要kill的连接id都查询出来
复制中间的kill id;内容到word文档
替换掉符号“|”和回车符(在word中查询^p即可查询到回车符)
把修改过的内容复制回终端,最后按回车执行

产生这种问题的原因是:

连接数超过了 MySQL 设置的值,与 max_connections 和 wait_timeout 都有关系。wait_timeout 的值越大,连接的空闲等待就越长,这样就会造成当前连接数越大。

解决方法:

修改MySQL配置文件/etc/my.cnf,设置成max_connections=1000,wait_timeout=5。如果没有此项设置可以自行添加,修改后重启MySQL服务即可。要不经常性报此错误,则要对服务器作整体性能优化

注:

为了防止发生too many connections时候无法登录的问题,mysql manual有如下的说明:

mysqld actually allows max_connections+1 clients to connect. The extra connection is reserved for use by accounts that have theSUPER privilege. By granting the SUPER privilege to administrators and not to normal users (who should not need it), an administrator can connect to the server and use SHOW PROCESSLIST to diagnose problems even if the maximum number of unprivileged clients are connected.

因此, 必须只赋予root用户的SUPER权限,同时所有数据库连接的帐户不能赋予SUPER权限。前面说到的报错后无法登录就是由于我们的应用程序直接配置的root用户

总结,解决问题的最终方法:

1.修改配置文件/etc/my.cnf,调整连接参数

2.检查程序代码,对于没有关闭的链接及时进行关闭