售前咨询400-838-0503

MySQL连接数过多怎么办?

发布:2026-11-05 13:54

搜索全部帮助分类的文档

网站突然提示数据库连接失败,应用日志出现以下错误,通常意味着MySQL实例的可用连接已被占满:

ERROR 1040 (HY000): Too many connections

常见原因包括应用连接未释放、连接池设置过大、慢查询导致请求积压,以及实际并发超过当前连接上限。建议按照下面的步骤排查。

1. 确认错误并登录目标数据库

先查看网站或应用日志,确认具体错误是 Too many connections。

如果提示密码错误、连接超时、账号连接数超限,或者应用连接池获取连接超时,需要分别排查,不能直接认定为实例连接数不足。

使用有权限的管理账号登录数据库。例如,采用本机密码认证时:

mysql -u root -p

按提示输入密码。远程数据库、自定义端口或容器部署环境,应使用实际的连接方式。

登录后确认当前实例:

SELECT VERSION(), @@hostname, @@port;

后续SQL语句均在MySQL客户端中执行,不是在Linux命令行直接执行。

如果已有可用的管理会话,排查期间建议保留,避免退出后无法重新连接。

2. 查看连接上限和当前使用情况

查询实例允许的最大连接数:

SHOW GLOBAL VARIABLES LIKE 'max_connections';

再查询连接相关指标:

SHOW GLOBAL STATUS
WHERE Variable_name IN (
  'Threads_connected',
  'Threads_running',
  'Max_used_connections',
  'Connection_errors_max_connections'
);

重点关注以下内容:

指标 含义 排查重点
max_connections 实例允许的最大连接数 当前配置是否适合业务规模
Threads_connected 当前打开的连接数 是否持续接近连接上限
Threads_running 当前未休眠的线程数 是否伴随执行、锁等待等积压
Max_used_connections 历史同时连接数峰值 是否曾接近或达到上限
Connection_errors_max_connections 因达到连接上限而被拒绝的累计连接次数 故障期间是否继续增加

例如,连接上限为151,当前连接数为150,说明可用余量已经较小。但这只是一次采样,仍需结合报错时间和拒绝计数判断。

Max_used_connections 是历史峰值,连接释放后不会立即下降;拒绝连接计数也应比较前后增量,不能仅凭数值非零判断故障仍在持续。

MySQL查看最大连接数和当前连接数

3. 找出连接来自哪个应用

执行:

SHOW FULL PROCESSLIST;

重点查看以下字段:

字段 含义
Id 连接编号
User 数据库账号
Host 客户端来源地址及端口
db 当前使用的数据库
Command 当前命令类型,例如Query或Sleep
Time 处于当前状态的时长,单位为秒
State 当前执行或等待状态
Info 当前执行的SQL内容

拥有 PROCESS 权限的账号可以查看其他用户的连接;权限不足时,通常只能看到自身账号的连接,不能据此判断整个实例的情况。

如果大量连接集中在同一个账号或来源地址,应优先检查对应的网站、后台任务或应用服务。

Sleep表示连接当前空闲,不等于连接异常。 连接池正常运行时也会保留空闲连接,而且空闲连接可能仍存在未结束的事务。

需要进一步核对InnoDB事务时,可由有相应权限的管理员执行:

SELECT
  trx_mysql_thread_id,
  trx_started,
  trx_state
FROM information_schema.innodb_trx;

其中 trx_mysql_thread_id 可以与连接列表中的 Id 对照,帮助定位长时间未结束的事务。

不要仅凭Sleep状态或空闲时长批量结束连接,应先确认连接用途、事务状态和业务影响。

MySQL使用SHOW FULL PROCESSLIST查看连接来源

4. 检查连接池、连接释放和慢查询

定位到连接来源后,重点检查以下几项。

检查连接是否正确释放

应用完成数据库操作后,应按照框架要求关闭连接或归还连接池。异常、超时、提前返回等代码路径,也需要执行连接释放逻辑。

如果访问量已经下降,连接数仍持续增长,应重点检查连接泄漏和后台任务积压。

计算全部应用的连接池总量

连接池上限通常作用于单个连接池,需要汇总所有进程、容器和应用实例。

例如,4个应用实例各使用一个最大连接数为30的连接池,理论上可能占用120个数据库连接。还需要计算后台任务、监控工具和管理连接,并预留余量。

如果每个进程都有独立连接池,还应继续乘以实际进程数量。

检查慢查询与长事务

查询执行缓慢、锁等待或事务迟迟不提交,都可能让连接长期无法归还,引发后续请求排队。

此时应结合慢查询日志、执行计划和事务信息定位原因。单纯增加连接上限,可能让更多请求同时进入数据库,进一步增加负载。

控制异常请求和重试

确认某个任务或服务正在异常创建连接后,可先暂停该任务或降低并发,并设置合理的重试间隔,缓解持续连接压力。

5. 资源允许时调整连接上限

确认业务确实需要更多连接,并评估内存、CPU和查询负载后,再调整 max_connections。

修改前记录原值。下面的200仅用于演示,不是通用推荐值。

临时调整运行中的连接上限:

SET GLOBAL max_connections = 200;

查询确认:

SHOW GLOBAL VARIABLES LIKE 'max_connections';

SET GLOBAL 只修改当前运行实例,数据库重启后会重新按照启动配置加载。

对于支持 SET PERSIST 的MySQL 8.0、8.4等版本,验证调整效果后,可以持久化配置:

SET PERSIST max_connections = 200;

该语句会设置运行值,并将配置写入数据目录中的 mysqld-auto.cnf,供后续启动加载。执行需要相应管理权限,不建议手工编辑这个文件。

对于不支持此语法的版本,应修改实际生效的MySQL配置文件,在 [mysqld] 段中设置,例如:

[mysqld]
max_connections=200

配置文件变更通常需要在维护窗口重启服务后生效。容器部署还应确认配置和数据目录具备持久化存储。

如果调整后负载明显升高,应根据记录恢复原运行值,并同步恢复对应的持久化配置。

MySQL使用SET PERSIST调整并验证最大连接数

6. 验证业务是否恢复

调整完成后,重新执行第2节中的查询,并在实际业务访问期间持续观察:

  • 网站、接口和后台任务能正常连接数据库。

  • 当前连接数保留合理余量,没有持续顶满。

  • 因连接上限产生的拒绝次数不再增加。

  • CPU、内存和查询响应时间保持稳定。

如果连接数很快再次达到上限,应继续检查连接泄漏、连接池总量和慢查询,而不是反复提高参数。

后续数据库正常重启后,也应再次核对 max_connections,确认持久化配置按预期生效。

常见问题

为什么连接数很多,CPU却不高?

部分连接可能处于空闲或等待状态。它们仍占用连接名额,但不一定持续消耗大量CPU,需要结合连接状态和事务情况判断。

直接重启MySQL能解决吗?

重启会中断现有连接,可能暂时恢复访问。如果应用连接泄漏或连接池设置不合理,故障仍可能再次出现。应先定位连接来源并处理根因。

连接满了,管理员还能登录吗?

MySQL为具备相应管理权限的账号保留了额外连接,但能否使用取决于账号权限及保留连接的占用情况。优先使用已有管理会话;不要为普通业务账号授予高权限来绕过限制。

注意事项

修改前记录参数原值及配置来源,避免回退时只恢复运行值而遗漏持久化设置。结束连接可能影响正在执行的业务及未提交事务,应确认用途后再处理。

本文以MySQL为例,MariaDB及其他兼容数据库的语法、权限和参数行为应以对应版本文档为准。

使用莱卡云服务器时,如需协助排查,可向莱卡云技术支持提供报错时间、MySQL版本、连接指标及脱敏后的连接列表。提交前请隐藏密码、业务SQL中的敏感数据和其他凭据信息。

按文档操作后还是不行,把机器编号、出问题的时间点和现象截图一起提工单,能少来回一轮。

提交工单