数据库连接池耗尽:排查顺序与三层兜底


column: 后端排障实战

order: 2
paid: false
teaser: false

一、先把问题边界说清楚

连接池耗尽通常是慢查询、长事务、连接泄漏或突发并发共同作用的结果。很多失败并不是工具本身失效,而是输入、状态、依赖和成功条件没有定义清楚。开始动手前,先写下触发条件、期望结果、允许的副作用和停止条件,这四项能挡住大部分无效尝试。

排障时最危险的动作是看到一个现象就直接改配置。更可靠的方法是先确定影响范围,再保存证据,提出可以被日志或指标证伪的假设。一次只验证一个变量,才能知道恢复究竟来自哪项操作。

检查项 要回答的问题 建议证据
输入 数据是否完整且版本正确 样例、校验结果
状态 当前处于哪个处理阶段 日志、状态文件
依赖 外部服务是否可用 延迟、错误码
结果 怎样才算真正成功 地址、记录、断言

二、用最小示例验证关键假设

先看等待连接数和借用时长,再检查数据库活动会话与应用归还路径。下面的示例刻意只保留关键动作,先在测试环境或授权数据上运行。确认输出符合预期后,再加入并发、重试与调度,避免一次引入过多变量。

text 复制代码
SELECT pid, state, now()-query_start AS age, query
FROM pg_stat_activity
WHERE state <> 'idle'
ORDER BY age DESC;

执行时为每次运行生成唯一标识,并把开始时间、关键参数摘要、阶段结果和耗时写进结构化日志。日志不要记录密码、会话值或完整个人数据;需要关联时使用内部生成的任务编号。任何写操作都应准备可逆路径,无法确认结果时先进入待核验状态。

三、把异常路径设计在正常路径之前

常见异常可以归为四类:输入不合法、依赖暂时不可用、动作结果未知、结果明确失败。输入问题直接拒绝并说明字段;暂时故障可以有限重试;未知状态必须查询或人工核验;明确失败则保存现场并停止。把所有异常都粗暴重试,会放大压力并制造重复结果。

重试应设置次数上限、递增间隔和幂等条件。对于不可重复的动作,先写任务记录,再执行外部操作,最后补充结果标识。进程退出后根据记录恢复,而不是从第一步盲目重来。这样即使机器重启或网络抖动,也能说明每项任务停在哪里。

四、上线前的验收清单

本文最值得持续观察的是池等待时间、活跃连接数和事务时长。先在小样本上制造一次可预期失败,确认日志能定位、告警能触达、任务能停止或恢复。随后再扩大数据量,并记录基线耗时和资源占用。

交付前还要补齐三类测试:正常流程验证主要结果,边界测试覆盖空值、超长输入和重复执行,故障测试模拟超时、页面变化或依赖中断。最后把启动、检查、恢复和清理命令写进 README,让没有参与开发的人也能按文档完成一次受控运行。

📌 本文是《后端排障实战》系列,持续更新,关注不迷路。

👉 下一篇:《一次 OOM 怎么定位:从系统指标追到代码分配点》,讲其中的关键实现、异常边界与验证方法。

💬 你在实际项目里遇到过高峰期请求长期等待数据库连接的问题吗?评论区聊聊。

(觉得有用点个赞+收藏,方便回头查阅)

🔧 相关可运行源码/资料已整理成资源包,可在我主页的资源里自取。

相关推荐
葡萄城技术团队3 小时前
1000 人协同压测的环境瓶颈排查:CPU 争用与 Wi\-Fi
前端
中云DDoS CC防护蔡蔡3 小时前
DDOS和CC攻击谁更可怕
运维·服务器·经验分享·网络安全·ddos
Ruiery3 小时前
Linux 6.6内核内存管理深度解析(十六):mmap — 用户态“申请内存“的真相
linux·运维·服务器
ClickHouseDB4 小时前
ClickHouse Cloud 与 Snowflake 实时性价比对比:CostBench 测试中的 412 倍差距来
运维·数据库·系统架构
m0_639906944 小时前
Redis入门|五种数据结构、使用场景、持久化RDB&AOF
数据结构·数据库·redis
欧米欧4 小时前
Linux系统篇(七),环境变量的底层溯源,核心获取机制与安全应用
linux·运维·服务器
Ruiery4 小时前
Linux 6.6内核内存管理深度解析(十八):KASLR 内核地址空间随机化
linux·运维·服务器·安全
excel4 小时前
Marked 与 Markdown 有什么区别?该怎么选?
前端
todoitbo5 小时前
群晖NAS部署JmalCloud:Docker安装、文件管理、博客与公网访问完整教程
运维·docker·容器
时间售卖铺5 小时前
触发器与函数实战:MySQL高效编程秘诀
运维·数据库·mysql·云原生