华为云 RDS for MySQL 报 Too many connections:连接数打满的定位与处理清单

举报
yd_294423728 发表于 2026/11/01 11:34:04 2026/11/01
【摘要】 RDS for MySQL 报 Too many connections 时,先在智能DBA助手实时会话里 Kill 空闲和问题会话止血,再按连接曲线是缓慢爬升还是瞬间飙升,分别排查连接泄漏、空闲堆积、长事务、连接风暴和慢 SQL 排队,最后再评估调大 max_connections 或升配,并给出连接池、超时和告警的预防配置与速查表。

华为云 RDS for MySQL 报 Too many connections:连接数打满的定位与处理清单

应用突然报 ERROR 1040 (HY000): Too many connections,新请求全部连不上库,这是 RDS for MySQL 上很常见的一类故障。很多人第一反应是把 max_connections 调大,但连接数打满往往只是表象,背后多半是连接泄漏、空闲连接堆积、慢 SQL 或连接风暴。这篇按「先止血、再定位、后预防」的顺序整理一份排查清单。

一、先确认是不是真的打满了

在还能连上的会话里(或者用控制台的工具)执行:

show status like 'Threads_connected';
show global variables like 'max_connections';

Threads_connected 接近或等于 max_connections,就可以确认是连接数打满。

控制台侧可以在实例的「智能DBA助手 > 实时性能」里看「当前活跃连接数」和「数据库总连接数」,切到历史趋势能看出是缓慢爬升还是瞬间飙升,两种情况的原因方向完全不同。

二、先止血:释放问题连接

  1. 进入实例的「智能DBA助手 > 实时会话」,按 Command 列筛出 Sleep 状态的会话,结合 Time 列找长时间空闲的连接;也可以按客户端 IP 统计,看是哪台应用机器占得最多。
  2. 选中空闲连接或问题会话,用「Kill会话」释放(支持批量)。
  3. 如果是某条高频 SQL 把连接拖住,可以在「智能DBA助手 > SQL分析与优化」里用「SQL限流」临时限制它的并发。

也可以用 SQL 先看一眼空闲超过 60 秒的连接:

select id, user, host, db, command, time, state
from information_schema.processlist
where command = 'Sleep' and time > 60
order by time desc;

注意:Kill 只是止血,不找到根因的话,连接很快又会涨回来。

三、按曲线形态定位原因

1. 缓慢上涨到上限

常见原因:

  • 连接泄漏:代码里拿了连接没归还(异常分支没 close、事务没结束)。按客户端 IP 统计,泄漏的那台机器连接数通常只涨不降。
  • 空闲连接堆积:wait_timeout / interactive_timeout 默认 28800 秒(8 小时),应用侧连接池又没配空闲回收,Sleep 连接越积越多。
  • 长事务未提交:会话一直挂着事务,连接被占住。可以查 information_schema.innodb_trx 里 trx_started 很早的事务。

2. 瞬间飙升

常见原因:

  • 连接风暴:应用集中启动时每个实例都初始化一大批连接;流量突增导致连接池快速扩容;连接池 maxTotal / maximumPoolSize 配置之和超过了实例上限;异常重试逻辑没有退避,失败后疯狂重连。
  • 数据库变慢导致排队:慢 SQL、锁等待、IO 瓶颈让每个请求占用连接的时间变长,连接数被动堆高。这时要去看慢 SQL 分析、锁与事务、IO 监控,而不是只盯连接数。

一个容易忽略的点:连接池数量要按「应用实例数 × 每实例最大连接数」算总账。比如 20 个 Pod、每个池子上限 50,理论峰值就是 1000,扩容 Pod 时这个数会跟着涨。

四、要不要调大 max_connections

可以调,但要清楚边界:

  • 修改位置:实例详情左侧「参数修改」,找到 max_connections 修改;官方文档说明该参数修改后立即生效,无需重启。如果改的是「参数管理」里的自定义参数模板,需要执行「应用」才会对实例生效。
  • 设成 default 时,上限随实例内存规格变化(官方 FAQ 给出的默认值例如 4GB 约 1500、8GB 约 2500、16GB 约 5000)。
  • 连接不是免费的。官方给的估算是单个连接大约占 1MB(thread_stack、join/sort/read buffer 等加起来),可用内存 = 总内存 − Buffer Pool − 约 1GB。盲目调大可能换来内存吃紧和性能下降。
  • 实际可用连接数还受单进程最大打开文件数限制,可以看 show variables like 'open_files_limit';。

如果业务确实需要更多连接,又受内存约束,就考虑规格升配。升配期间实例可访问,但会有秒级连接闪断,放在业务低峰期做。

五、预防:把连接管起来

  • 连接池上限:所有应用实例的连接池上限之和,控制在实例 max_connections 的 70%~80% 以内,给运维和突发留余量。
  • 空闲超时对齐:wait_timeout / interactive_timeout 可以按业务调到 600~1800 秒;同时让客户端连接池的空闲回收时间小于数据库的 wait_timeout,否则池子里会留下已被服务端断开的「僵尸连接」,借出去就报错。
  • 重试要退避:连接失败的重试加上指数退避和上限,避免故障时自己把数据库打爆。
  • 告警前置:给「连接数使用率」配告警,阈值同样设在 70%~80%,比等到 1040 报错再处理主动得多。
  • 定期巡检:按客户端 IP 看连接分布,发现某个服务连接只增不减,优先查泄漏。

六、速查表

现象 可能原因 怎么确认
连接数缓慢爬升、很少回落 连接泄漏 实时会话按 IP 统计,某来源只增不减
大量 Sleep 连接、Time 很大 wait_timeout 过大、池子不回收 processlist 筛 Sleep,看 Time
连接被占住且有未提交事务 长事务 innodb_trx 看 trx_started
发布或扩容瞬间打满 连接池初始化/总量超限 对照发布时间与连接曲线,核算池子总账
故障时连接越来越多 重试无退避 应用日志里的重连频率
连接数和慢 SQL 同时上涨 数据库变慢导致排队 慢 SQL 分析、锁等待、IO 监控

小结

遇到 Too many connections,我习惯先 Kill 空闲和问题会话止血,再看连接曲线是「慢涨」还是「突增」来分方向,最后才考虑调 max_connections 或升配。把连接池总量、空闲超时和告警阈值这三件事配好,大部分连接数打满的问题都能提前避开。

参考文档:

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0)

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。