数据库连接数飙升本质是旧连接未释放叠加新连接涌入,需区分瞬时冲击与持续堆积:查SHOW PROCESSLIST识别Sleep长连接、Query卡顿及重复IP建连;验证连接池idleTimeout与数据库wait_timeout匹配、启用test-on-borrow;排查长事务与慢SQL放大效应;检查负载均衡健康检查、K8s preStop及DNS缓存等基础设施问题。

流量切换时数据库连接数飙升,本质不是“新流量来了”,而是“旧连接没走、新连接又来”,叠加配置错位与资源争抢导致的雪崩。关键要区分是瞬时冲击还是持续堆积——前者看连接池响应能力,后者看泄漏或慢查询是否被放大。
一、先确认是不是真实连接激增
执行 SHOW PROCESSLIST,重点过滤三类异常:
- 大量 Command = Sleep 且 Time > 60 秒:说明连接空闲但未释放,极可能是旧实例连接未优雅下线,或连接池未感知切换而持续复用失效连接
- 大量 Command = Query + State = Sending data / Sorting result:新流量触发了未优化SQL,比如分页深度过大、缺失索引的WHERE条件,正在拖住连接
- 同一 Host 出现大量不同 Id 连接(尤其集中在某几个应用IP):说明该服务节点在切换过程中重复建连,可能因健康检查失败反复重试,或配置了短连接+无连接池
二、查连接池是否“双端失联”
流量切换常暴露连接池与数据库超时参数不匹配问题:
- 检查应用侧 idleTimeout(如 HikariCP 的
idle-timeout)是否小于数据库 wait_timeout 至少 30 秒;若不满足,切换后旧连接在池中“假存活”,取用时报 Communications link failure,触发重试逻辑,连接数指数增长 - 确认连接池是否开启 connection-test-query(如
SELECT 1)和 test-on-borrow;未启用时,失效连接被复用,失败后才重建,形成连接风暴 - 查看切换窗口期应用日志:是否有密集出现 Connection refused、Cannot get JDBC Connection 或重试计数陡增,这是连接池已打满但仍拼命建连的信号
三、盯住事务与慢查询是否被放大
流量切到新实例后,执行计划可能变化,原本不显眼的问题被引爆:
- 执行 SELECT * FROM information_schema.INNODB_TRX WHERE trx_started < NOW() - INTERVAL 30 SECOND,看是否有长事务卡住——切换时若存在未提交事务,新连接会排队等待锁
- 开启并检查 slow_query_log,阈值设为 1 秒;特别关注切换后前 5 分钟内新增的慢 SQL,常见于 JOIN 未走索引、ORDER BY + LIMIT 深度分页、统计类报表集中触发
- 对比新旧实例的 innodb_buffer_pool_size 和 sort_buffer_size 配置,若新库内存更小,原本能缓存的排序/临时表被迫落盘,SQL 执行时间拉长,连接占用周期变长
四、检查基础设施层是否“帮倒忙”
有些问题藏在流量网关或容器调度背后:
- 确认负载均衡器(如 Nginx / ALB)的健康检查间隔是否过短,或失败重试次数过多;一次短暂抖动可能触发多轮探测+重试,误判实例不可用,导致流量反复来回切
- 如果是 Kubernetes 环境,检查 Pod 重启策略和 preStop hook:是否设置了
sleep 30给连接池足够时间归还连接?没有的话,Pod 被强制终止,连接直接断在中间 - 验证 DNS 缓存 TTL 是否过长,客户端本地缓存了旧 IP,部分请求仍打向老库,造成双写+双连,加剧新库压力

















