MySQL数据库连接数过多,Too many connections解决
时间:2026-10-5 08:47 作者:emer 分类: 无
前言
做网站开发的同学肯定遇到过这个错误:用户访问网站的时候,突然报错了,说"MySQL连接失败:Too many connections"。这时候网站就打不开了,用户都在骂娘,你急得满头大汗不知道怎么办。
这个错误其实很常见,就是MySQL的最大连接数不够用了。很多新手同学遇到这个错误就慌了,不知道怎么处理。这篇文章就把这个问题的原因和解决方法讲清楚,以后再遇到就不用慌了。
一、为什么会出现Too many connections错误
MySQL默认的最大连接数是151,这个数在小项目里够用,但是如果项目用户多了,或者连接池设置得太大,就很容易把连接数占满。
当所有连接都被占满的时候,新的请求就进不来了,这时候MySQL就会报"Too many connections"的错误。
常见原因
- 应用程序连接池设置太大:比如你的应用配置了500个连接,但是MySQL最大连接数才151,那肯定不够用
- 慢SQL太多:很多SQL执行得很慢,连接迟迟不释放,占着茅坑不拉屎
- 连接没有及时释放:应用程序写完代码忘了关闭连接,导致连接泄漏
- 突发流量:突然来一波大流量,把连接数占满了
二、查看当前连接数和最大连接数
先看看你的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
八、从根本上解决问题
光调大最大连接数只是治标不治本,要从根本上解决问题,还得从应用层面下手:
- 检查应用程序是不是有连接泄漏:用完连接记得释放,不要一直占着
- 优化慢SQL:把执行慢的SQL优化一下,减少连接占用时间
- 合理设置连接池大小:连接池不要设得太大,比最大连接数小一点就行
- 使用连接池中间件:比如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错误的解决方法:
- 先查看当前最大连接数和已用连接数
- 临时救急:用SET GLOBAL调大max_connections
- 永久解决:改my.cnf配置文件,设置max_connections
- 看看连接都是从哪来的,有没有异常
- 优化慢SQL,减少连接占用时间
- 设置wait_timeout,自动断开空闲连接
- 从应用层面优化,减少连接泄漏
记住:调大最大连接数只是治标,优化SQL和代码才是治本。不要一遇到连接数不够就盲目调大max_connections,先找找根本原因。
遇到问题加QQ23979811 协助处理