排查 MySQL Too many connections,区分全局与账号上限,定位连接池、慢查询和重试风暴,安全止损并验证连接预算。
先恢复管理入口,不要先无限加连接数:MySQL 报 Too many connections,表示普通客户端可用连接已经被占满。先通过服务器本机、云数据库控制台或保留的管理账号连接,读取 Threads_connected、Max_used_connections 和进程列表,找出是连接池过大、慢查询占住连接、应用重试风暴,还是连接没有正确释放。直接把 max_connections 调得很高会增加内存和文件描述符压力,可能把“拒绝新连接”升级为整库 OOM 或卡死。
数据与操作风险:读取状态不收费,也不修改数据。执行 KILL、重启 MySQL 或改连接参数可能中断请求,未提交事务会回滚;配置错误会让数据库无法启动。操作前确认备份和恢复入口,保存当前参数与配置文件,先暂停异常应用的重试或流量,避免刚释放的连接立即再次被占满。
先确认是全局上限还是单个账号上限
应用日志中 Too many connections 通常指全局连接上限;Too many user connections 或用户资源限制相关错误,则可能是某个账号的并发限制。能登录时执行下面的只读 SQL:
SHOW VARIABLES LIKE 'max_connections';
SHOW VARIABLES LIKE 'max_user_connections';
SHOW GLOBAL STATUS LIKE 'Threads_connected';
SHOW GLOBAL STATUS LIKE 'Max_used_connections';
SHOW GLOBAL STATUS LIKE 'Connection_errors_max_connections';
SHOW FULL PROCESSLIST;
Threads_connected 是当前连接数,Max_used_connections 是本次服务启动以来的峰值。进程列表要关注用户、来源主机、数据库、命令、持续时间和当前 SQL。不要把完整 SQL、账号和来源地址复制到公开工单;其中可能含业务数据和内部网络信息。
完全无法登录时怎么拿到排障入口
MySQL 会为具有管理连接权限的账号保留额外连接能力,但前提是事先正确配置并且管理员没有和应用共用账号。托管数据库优先使用云控制台的会话管理、性能洞察或管理连接,不要重启作为第一步。自建 MySQL 可从服务器本机使用专用管理账号;若应用正在高速重试,先在负载均衡、应用服务或任务队列侧暂停异常实例,让连接有机会释放。
不要为了抢连接把普通应用账号授予 CONNECTION_ADMIN 或高权限。长期方案是把管理账号、应用账号和只读任务分开,并为连接数、拒绝次数和使用率提前告警。
进程列表里常见的四种根因
| 现象 | 说明 | 优先处理 |
|---|---|---|
大量 Sleep | 连接池总量过大或空闲时间过长 | 按应用实例数核算池大小,降低空闲连接和泄漏 |
| 同一 SQL 长时间运行 | 慢查询、锁等待或下游存储慢 | 看执行计划、锁和索引,先停止异常流量 |
| 同一来源短时间大量连接 | 重试风暴或没有复用连接 | 暂停异常实例,增加退避和连接池 |
| 后台任务集中爆发 | cron、队列或批处理并发失控 | 限制任务并发并错峰,不与在线请求争满连接 |
Sleep 并不自动等于“无用”。它可能是连接池为后续请求保留的正常连接。应同时看数量、空闲时间、应用实例数和池配置。若有 20 台应用,每台池上限 50,理论上就可能产生 1000 条连接;数据库的 max_connections 设为 500 时,问题来自总量设计而不是数据库突然变小。
紧急止损怎样避免误杀事务
- 先在应用侧暂停产生连接风暴的实例、队列消费者或定时任务。
- 确认进程 ID、账号、来源、持续时间和事务状态。
- 优先终止确定无业务价值的异常查询,而不是批量杀掉所有连接。
- 观察拒绝次数、连接数、锁等待和应用错误率是否下降。
- 只有数据库已失去响应且没有更安全管理入口时,才按维护流程评估重启。
KILL QUERY 只停止当前语句,连接仍保留;KILL CONNECTION 会断开会话,并使未提交事务回滚。大事务回滚可能持续很久并继续消耗 IO,所以不能看到线程消失就认为恢复完成。批量脚本尤其危险,必须先输出目标清单并人工核对。
max_connections 应该怎样安全调整
先计算业务需要:Web、后台任务、管理、监控、复制和维护分别需要多少连接,再留出故障缓冲。MySQL 每个连接会使用线程、缓冲区和文件描述符,真实内存取决于工作负载与会话缓冲,不存在适合所有 2 核 4 GB 服务器的固定数字。
临时动态调整只能用于已确认数据库还有资源、且应用池总量确实合理的场景。随后还要把受控数值写入正确配置文件并安排重启验证;否则服务重启后会恢复旧值。托管数据库应在参数模板中修改,并先确认是否需要重启、允许范围和规格上限。增加连接数前同时检查内存、文件描述符、CPU、磁盘延迟和数据库线程模型。
应用连接池应该怎样配
把数据库可用连接预算分给所有应用副本,而不是每台都使用数据库上限。连接池最小值不必等于最大值;低流量实例可以按需建立。为获取连接设置短而合理的等待时间,失败时采用指数退避和熔断,不要立即无限重试。请求结束、异常分支和后台任务都要释放连接;部署时先让旧实例退出流量再扩大新实例,避免滚动发布期间连接数翻倍。
慢查询会延长每条连接占用时间,因此连接耗尽与 SQL 性能经常同时出现。可以结合MySQL 慢查询排查和Linux 高负载排查。若团队长期无法承担连接、备份和高可用运维,可参考托管数据库与自建数据库选型,但迁移本身不是当天止损手段。
怎样验收,怎样回退
- 在相同业务时段观察
Threads_connected、峰值和拒绝次数。 - 确认应用连接池等待、错误率和请求尾延迟恢复。
- 检查锁等待、慢查询、CPU、内存和文件描述符没有恶化。
- 重启一个应用副本,确认连接能正常回收和重新建立。
- 在维护窗口验证数据库重启后参数仍生效,管理入口仍可用。
调高参数后内存或延迟恶化时,先把应用池和异常流量降回安全范围,再恢复原 max_connections;不能在现有连接仍超过旧上限时直接硬降并重启。保留原配置和监控基线,按小步变更、观察、再扩大的顺序处理。

