网站突然显示数据库连接失败,MySQL日志或应用里出现 Too many connections,说明可用连接已经被占满。最直接的办法是调大 max_connections,但这不一定能解决问题,反而可能让小内存VPS更快耗尽内存。
我更建议先回答两个问题:连接为什么没有及时释放,当前服务器能不能承受更多并发连接。本文从连接状态、应用连接池、慢查询和配置上限逐层排查。

一、Too many connections是什么意思
MySQL用 max_connections 控制同时允许的客户端连接数。所有普通连接都被占用后,新请求就会收到这个错误。
先查看当前上限、正在使用的连接和历史峰值:
SHOW VARIABLES LIKE 'max_connections';
SHOW STATUS LIKE 'Threads_connected';
SHOW STATUS LIKE 'Max_used_connections';
SHOW STATUS LIKE 'Connection_errors_max_connections';
Threads_connected 是当前连接数,Max_used_connections 是服务器启动以来的峰值。只看某一时刻的当前值,可能会错过刚刚发生的连接洪峰。
二、先找出连接都被谁占用了
具有相应权限的管理账号可以执行:
SHOW FULL PROCESSLIST;
重点看 User、Host、db、Command、Time 和 State。大量长期 Sleep 连接常见于连接池配置过大或应用没有及时释放连接;大量执行中的同类SQL,则可能是慢查询、锁等待或突发流量。
MySQL会额外保留一个管理连接名额给具备 CONNECTION_ADMIN 权限的账号,便于连接数耗尽后排查。不要把管理权限授予普通网站账号。
三、常见根因不只是访问量上涨
连接数被占满,常见来源可以归为四类:
- 应用连接池总量过大,多个进程、容器或站点叠加后超过MySQL上限。
- 代码异常退出、连接泄漏或超时时间过长,大量Sleep连接迟迟不释放。
- 慢查询、表锁或事务未提交,让请求在数据库里排队。
- 爬虫、攻击、定时任务或流量突增,短时间创建大量连接。
例如8个应用进程,每个连接池允许30个连接,理论上就可能占用240个。配置时必须按实例数乘以每个实例的连接池上限计算,不能只看单个进程。
四、临时恢复服务应该怎么做
先保留现场信息,导出 SHOW FULL PROCESSLIST 和关键状态,再决定是否终止明显异常的连接。可以使用:
KILL CONNECTION 连接ID;
不要批量杀掉所有连接,正在执行的写入事务可能回滚并加重负载。若应用明显失控,应先限制或重启故障应用,再处理数据库连接,否则新连接会立刻重新占满。
临时提高上限可使用:
SET GLOBAL max_connections = 200;
它只对新连接生效,而且重启后可能恢复原值。数值要结合内存余量调整,不能把200、500或1000当成通用答案。
五、怎样设置永久连接上限
MySQL配置文件位置会因系统和安装方式不同而变化,常见位置包括 /etc/mysql/mysql.conf.d/mysqld.cnf 和 /etc/my.cnf。在 [mysqld] 段加入:
[mysqld]
max_connections = 200
修改后先检查配置,再选择低峰重启MySQL。生产环境应同时观察内存、Swap、查询延迟和错误日志,确认提高连接数没有把压力转移成OOM或磁盘换页。
连接数越高,潜在并发内存占用越大。max_connections不是性能参数,调大只代表允许更多请求同时进入数据库。
六、从应用侧减少无效连接
应用连接池的最小连接数不宜过高,最大连接数要根据实例总量统一预算。连接空闲超时、请求超时和数据库 wait_timeout 也应协调,避免一边长期保留,一边被数据库提前断开。
WordPress等PHP站点通常每次请求建立连接并在请求结束后释放。若大量连接持续堆积,应检查插件、定时任务、PHP-FPM进程数和慢查询,而不是只在MySQL侧加上限。
容器部署还要统计所有副本。水平扩容应用时,数据库连接数会随副本数量一起增长,这一点很容易在流量增长时被忽略。
七、慢查询和锁等待怎么查
在 SHOW FULL PROCESSLIST 中看到大量相同SQL、Locked 或长时间执行状态时,先查锁和慢查询。MySQL 8可以结合 Performance Schema、慢查询日志和 EXPLAIN 判断索引与扫描情况。
修复方向可能是增加合适索引、缩短事务、减少一次查询的数据量、避免后台任务集中执行,或在应用层增加缓存。只有把连接占用时间降下来,相同的连接上限才能承受更多请求。
八、什么时候才需要升级服务器
连接池已合理、慢查询已处理,业务并发仍持续增长,并且内存、CPU与磁盘IO接近上限时,才需要考虑增加资源或拆分数据库。升级之前先看一周以上的峰值,而不是根据一次报错立刻买高配。
希望保留灵活升级空间,可以选择支持快照和配置调整的平台,例如 萤光云 和 **LightNode**。数据库迁移前要先验证备份恢复,并安排明确的停写和回滚方案。
常见问题
问:直接把max_connections改成1000可以吗?
答:不建议。应根据内存、连接池总量和历史峰值计算,过高可能引发OOM。
问:大量Sleep连接正常吗?
答:少量连接池空闲连接正常,数量长期接近上限则需要检查池大小和超时。
问:重启MySQL能解决吗?
答:只能暂时清空连接,应用泄漏、慢查询或流量问题仍会再次触发。
问:怎样知道历史连接峰值?
答:查看Max_used_connections,并结合监控记录重启前后的数据。
问:连接数满了为什么管理员还能登录?
答:MySQL会为具备CONNECTION_ADMIN等权限的管理账号保留额外连接。
温馨提示
排查Too many connections时,先保存进程列表和状态指标,再恢复服务。连接上限、应用连接池、慢查询和服务器内存需要一起看,只改一个数字很容易把故障推迟到下一次高峰。


