用心打造
VPS知识分享网站

MySQL连接数突然打满怎么办?连接来源与连接池排查

应用突然报 Too many connections,最直接的做法是把 max_connections 调大。但连接上限被打满只是结果,背后可能是流量增长、应用发布后连接池失效、连接泄漏、慢SQL堆积、数据库变慢导致连接归还不及时,甚至是异常客户端不断重连。

连接数上限不是越大越好。每个连接都会消耗线程、会话缓冲区和文件描述符,活跃查询还会争抢CPU、内存、锁与磁盘。数据库已经过载时继续放入更多连接,可能把偶发错误变成整体雪崩。

连接数打满

先确认上限、当前量和增长速度

保留现有管理会话,不要在高峰时反复断开重连。执行:

SHOW VARIABLES LIKE 'max_connections';
SHOW GLOBAL STATUS LIKE 'Threads_connected';
SHOW GLOBAL STATUS LIKE 'Threads_running';
SHOW GLOBAL STATUS LIKE 'Max_used_connections';
SHOW GLOBAL STATUS LIKE 'Connections';
SHOW GLOBAL STATUS LIKE 'Aborted_connects';

Threads_connected 是当前打开的连接,Threads_running 更接近正在执行而非休眠的线程。连接很多但运行线程很少,重点检查Sleep会话、连接池最小连接数和空闲回收;两者同时很高,则数据库可能正在被慢查询、锁等待或资源瓶颈拖住。

Max_used_connections 是启动以来的峰值,只能说明历史上到过多高。Connections 是累计尝试数,应按监控时间窗口计算速率。每秒新建连接突然上升,常见于连接池未复用、健康检查过密或失败重试。

保留紧急管理入口

连接已经满时,普通账号可能无法登录。MySQL通常会为具备相应管理权限的账号保留额外连接能力,但版本与权限模型不同,不能默认任何root账号都能进入。应提前建立仅用于故障处理的本地管理路径,并限制来源与权限。

不要在故障时把应用账号直接提升为管理员。也不要频繁执行批量Kill,先确保能识别业务关键事务、备份任务和复制线程。高可用环境还要确认当前连接的是主库、只读副本还是代理入口。

通过Unix Socket登录能绕开部分网络路径,但不能绕开MySQL连接上限和权限检查:

mysql --protocol=socket -uroot -p

密码不要写入命令行或脚本参数,避免进入历史记录和进程列表。

按用户、主机和状态统计来源

MySQL 8.0可优先使用Performance Schema或sys视图,旧版本可用 SHOW FULL PROCESSLIST。先做聚合,再决定是否查看明细:

SELECT USER, HOST, COMMAND, COUNT(*) AS connection_count,
       MAX(TIME) AS max_seconds
FROM information_schema.PROCESSLIST
GROUP BY USER, HOST, COMMAND
ORDER BY connection_count DESC;

这里的 HOST 往往包含客户端端口。同一IP会出现多个值,按主机聚合时需要谨慎处理,不能直接用字符串完全相等判断应用实例。经过数据库代理时,MySQL看到的来源可能都是代理地址,应继续到代理和应用监控中拆分。

关注 COMMAND 为Sleep且持续时间很长的连接、某个新版本应用突然占据大多数连接,以及相同查询大量处于Sending data、Locked或Waiting状态。状态名称随版本和执行阶段变化,不能只凭一个词下结论。

区分空闲堆积、慢查询与锁等待

空闲连接多不一定是泄漏。连接池会保留一定数量以减少握手成本,但所有实例的最小连接数相加可能远超预期。例如20个实例每个保持50条空闲连接,数据库启动后就会占用1000个槽位。

活跃连接多时,读取完整语句与持续时间:

SELECT ID, USER, HOST, DB, COMMAND, TIME, STATE, LEFT(INFO, 300) AS SQL_TEXT
FROM information_schema.PROCESSLIST
ORDER BY TIME DESC;

输出可能包含敏感SQL和参数,保存前应脱敏。大量线程执行同一慢SQL,应先分析执行计划、索引与等待,不要只增加连接。大量线程处于锁等待,则先定位阻塞事务。数据库CPU、I/O或存储延迟升高也会让每个请求占用连接更久,最终把连接池拖满。

核对应用连接池总预算

连接池配置必须按应用实例总数核算,而不是只看单实例。建议列出每个服务的:

  • 实例数量
  • 每实例最小与最大连接数
  • 获取连接超时
  • 空闲回收时间
  • 连接最大生命周期
  • 请求失败后的重试次数

把这些数据放到同一张容量表中后,可以得到一个清晰的预算关系:所有应用池最大连接数之和,加上运维、任务、监控、复制和临时连接,应低于数据库安全上限,并保留故障处理余量。

滚动发布期间新旧实例会短暂同时存在,连接数可能接近两倍。自动扩缩容也会放大总池容量。连接池最大值不能仅按日常实例数计算,还要覆盖部署和故障切换场景。

检查连接泄漏与重试风暴

连接泄漏通常表现为某个应用实例的已借出连接持续增加、请求结束后不归还,最终获取连接超时。应结合应用连接池指标、线程栈和请求追踪,而不是只从MySQL端猜测。

网络抖动或数据库短暂变慢时,错误重试可能快速创建新连接。检查应用是否使用指数退避和抖动,是否在每次请求中创建连接,以及健康检查是否绕过连接池。多个实例同时固定间隔重试会形成同步风暴。

wait_timeout 可以回收长时间空闲的非交互连接,但调得过短会让连接池拿到已被服务端关闭的连接,产生更多重连和错误。修改前应先确认连接池验证、保活和最大生命周期设置,再让服务端与客户端策略匹配。

什么时候可以调整max_connections

先查看当前变量来源和系统容量:

SHOW VARIABLES LIKE 'max_connections';
SHOW VARIABLES LIKE 'thread_cache_size';
SHOW VARIABLES LIKE 'wait_timeout';

提高 max_connections 前要估算全局缓冲与每连接缓冲,检查文件描述符、线程、CPU和内存余量。排序缓冲、连接缓冲及临时表相关内存并非每条连接都同时达到最大,但高并发查询会显著放大实际使用。

临时动态调整可用于止血,但配置持久化方式随MySQL版本和安装方式不同。手工改运行值却不改配置文件,重启后会恢复;直接改配置又不验证启动参数,可能造成下次启动失败。

真正原因是连接池配置失控时,应先限制应用池和重试,而不是把数据库上限无限扩大。业务确实增长、SQL与连接池已优化且资源充足时,再按容量计划提高上限。

紧急释放连接要注意什么

可以对确认无用的长时间Sleep连接或异常客户端连接执行 KILL CONNECTION ID,但必须逐条确认。Kill正在执行的事务会触发回滚,大事务回滚可能长时间占用I/O与锁,情况反而更严重。

KILL CONNECTION CONNECTION_ID;

不要从网上复制拼接后直接批量执行。先生成清单、核对用户、主机、库、状态、持续时间和SQL,再在业务负责人确认后处理。复制线程、备份、迁移和管理连接必须排除。

当现有环境难以区分应用池与数据库容量问题,可以在 萤光云 建立同版本的脱敏数据库对照,或在按小时计费的 LightNode 上模拟不同连接池上限。只使用合成数据和压测账号,不能把生产库直接复制到公开测试环境。

修复后怎样验收

验收至少要跨过真实高峰和一次滚动发布。持续观察 Threads_connectedThreads_running、连接创建速率、获取连接等待、数据库延迟、错误率和内存。

SHOW GLOBAL STATUS LIKE 'Threads_connected';
SHOW GLOBAL STATUS LIKE 'Threads_running';
SHOW GLOBAL STATUS LIKE 'Max_used_connections';
SHOW GLOBAL STATUS LIKE 'Aborted_connects';

连接峰值保持在预算范围内,Sleep会话能按预期回收,发布期间不会打满,慢查询或锁等待也不再让连接长时间堆积,才算真正修复。仅让 Too many connections 暂时消失不够。

最终应能解释每一类连接来自哪里、为何存在、何时释放,以及数据库在最坏部署场景下仍保留多少安全余量。

常见问题

Threads_connected很高但Threads_running很低,需要扩容吗?

不一定。先检查连接池最小值、Sleep持续时间和实例总数。它更可能是空闲连接预算过大,而不是查询并发真的很高。

把wait_timeout调小能快速清理连接吗?

可能清理长时间空闲连接,也可能导致连接池频繁拿到失效连接并重连。必须与客户端的空闲回收、保活和连接生命周期一起设计。

max_connections应该设置多大?

没有统一数字。它取决于实例内存、每连接工作负载、应用池总预算、管理余量与性能目标。应通过监控和压测确定,不要按CPU核数或内存大小套固定公式。

赞(0)
未经允许不得转载;国外VPS测评网 » MySQL连接数突然打满怎么办?连接来源与连接池排查
分享到