MySQL数据库连接数过多,Too many connections解决

前言

做网站开发的同学肯定遇到过这个错误:用户访问网站的时候,突然报错了,说"MySQL连接失败:Too many connections"。这时候网站就打不开了,用户都在骂娘,你急得满头大汗不知道怎么办。

这个错误其实很常见,就是MySQL的最大连接数不够用了。很多新手同学遇到这个错误就慌了,不知道怎么处理。这篇文章就把这个问题的原因和解决方法讲清楚,以后再遇到就不用慌了。

一、为什么会出现Too many connections错误

MySQL默认的最大连接数是151,这个数在小项目里够用,但是如果项目用户多了,或者连接池设置得太大,就很容易把连接数占满。

当所有连接都被占满的时候,新的请求就进不来了,这时候MySQL就会报"Too many connections"的错误。

常见原因

  1. 应用程序连接池设置太大:比如你的应用配置了500个连接,但是MySQL最大连接数才151,那肯定不够用
  2. 慢SQL太多:很多SQL执行得很慢,连接迟迟不释放,占着茅坑不拉屎
  3. 连接没有及时释放:应用程序写完代码忘了关闭连接,导致连接泄漏
  4. 突发流量:突然来一波大流量,把连接数占满了

二、查看当前连接数和最大连接数

先看看你的MySQL现在最大连接数是多少:

SHOW VARIABLES LIKE 'max_connections';

执行完之后会看到类似这样的结果:

+-----------------+-------+
| Variable_name   | Value |
+-----------------+-------+
| max_connections | 151   |
+-----------------+-------+

再看看当前有多少个连接:

SHOW STATUS LIKE 'Threads_connected';

结果类似:

+-------------------+-------+
| Variable_name     | Value |
+-------------------+-------+
| Threads_connected | 120   |
+-------------------+-------+

你看,当前已经用了120个连接,最大才151,再涨一点就满了。

三、临时调整最大连接数

如果现在已经出现Too many connections错误了,可以先临时把最大连接数调大一点,救个急:

SET GLOBAL max_connections = 500;

这个命令执行完之后立刻生效,不用重启MySQL。但是注意:这个修改是临时的,MySQL重启之后就会恢复成原来的值。

四、永久修改最大连接数

要永久修改的话,需要改配置文件。找到MySQL的配置文件 /etc/my.cnf,在 [mysqld] 下面添加:

[mysqld]
max_connections = 1000

修改完之后重启MySQL服务:

systemctl restart mysqld

这样以后MySQL重启之后最大连接数还是1000,不会变回去。

注意:不要设得太大

很多同学觉得既然不够用,那就设大点,直接设个10000。这是不对的。

每个连接MySQL都要分配内存,如果连接数设得太大,每个连接占的内存加起来就很多了,可能会把服务器内存吃满。

一般来说,最大连接数设到500~1000就够了,要看你的服务器内存有多大。内存大就设大点,内存小就设小点。

五、查看连接是从哪来的

如果连接数突然涨得很猛,你得看看这些连接都是从哪来的,是不是有哪个程序疯了一直在创建连接。

SELECT 
    host, 
    COUNT(*) AS count
FROM information_schema.processlist
GROUP BY host
ORDER BY count DESC;

这个命令会把每个IP的连接数统计出来,你看看是不是某个IP连接特别多,如果是的话,就去查那个程序是不是有问题。

六、查看正在执行的SQL

如果很多连接都在执行SQL,那可能是慢SQL太多导致的。看看现在都在执行什么SQL:

SHOW PROCESSLIST;

执行完之后会列出所有正在运行的连接和SQL语句。你看看有没有执行了很久还没跑完的SQL,如果有的话,那就是罪魁祸首。

七、杀掉空闲连接

如果有很多连接都是空闲的(Sleep状态),占着连接不干活,那可以把它们杀掉,释放连接。

先看看有多少个Sleep状态的连接:

SELECT COUNT(*) FROM information_schema.processlist WHERE command = 'Sleep';

如果Sleep状态的连接很多,可以把它们杀掉。不过手动一个个杀太麻烦了,可以设置一个自动断开空闲连接的参数:

SET GLOBAL wait_timeout = 60;
SET GLOBAL interactive_timeout = 60;

这两个参数的意思是:连接如果空闲超过60秒,MySQL就自动把它断开,释放连接。

同样,这个修改是临时的,要永久生效的话需要写到配置文件里:

[mysqld]
wait_timeout = 60
interactive_timeout = 60

八、从根本上解决问题

光调大最大连接数只是治标不治本,要从根本上解决问题,还得从应用层面下手:

  1. 检查应用程序是不是有连接泄漏:用完连接记得释放,不要一直占着
  2. 优化慢SQL:把执行慢的SQL优化一下,减少连接占用时间
  3. 合理设置连接池大小:连接池不要设得太大,比最大连接数小一点就行
  4. 使用连接池中间件:比如MyCat、ProxySQL这些数据库中间件,可以统一管理连接

常见坑

坑1:改完max_connections之后重启又变回去了

很多同学用SET GLOBAL改完最大连接数之后,以为就完事了,结果MySQL一重启又变回原来的值。这是因为SET GLOBAL是临时修改,要永久生效必须改配置文件。

坑2:max_connections设得太大

很多同学一遇到连接数不够,就直接把max_connections改成10000,结果MySQL直接起不来了,或者服务器内存被吃满了。每个连接都要占内存,连接数越大,内存消耗越多,要根据服务器内存来设,不要盲目设大。

坑3:只改了max_connections,没改表连接数

其实MySQL还有一个参数叫max_user_connections,是限制单个用户的最大连接数的。如果你给某个用户限制了最大连接数,就算全局max_connections很大,那个用户的连接数到上限了还是会报错。

可以用这个命令查看:

SHOW VARIABLES LIKE 'max_user_connections';

坑4:杀掉了正在执行重要SQL的连接

很多同学一看到连接数满了,就不管三七二十一把所有连接都杀掉。结果把正在执行重要业务SQL的连接也杀了,导致业务出问题。杀连接之前一定要看清楚,不要乱杀。

总结

MySQL Too many connections错误的解决方法:

  1. 先查看当前最大连接数和已用连接数
  2. 临时救急:用SET GLOBAL调大max_connections
  3. 永久解决:改my.cnf配置文件,设置max_connections
  4. 看看连接都是从哪来的,有没有异常
  5. 优化慢SQL,减少连接占用时间
  6. 设置wait_timeout,自动断开空闲连接
  7. 从应用层面优化,减少连接泄漏

记住:调大最大连接数只是治标,优化SQL和代码才是治本。不要一遇到连接数不够就盲目调大max_connections,先找找根本原因。

遇到问题加QQ23979811 协助处理


emer 发布于  2026-10-5 08:47