当前位置: 首页 > news >正文

一次生产事故复盘:服务报 “Failed to obtain JDBC Connection” 的完整排查与解决

一次生产事故复盘:服务报 “Failed to obtain JDBC Connection” 的完整排查与解决


一、问题现象

系统运行一段时间后,开始频繁出现如下异常:

FailedtoobtainJDBCConnection;nested exception isjava.sql.SQLTransientConnectionException:swxx-Connectionis not available,request timed out after30000ms.

表现为:

  • 接口全部超时
  • 定时任务报错
  • 数据库连接获取失败
  • 服务响应变慢
  • 服务器 CPU 飙升接近 100%

重启服务后短暂恢复,运行一段时间再次复现。


二、第一反应(错误判断)

看到这个异常,第一直觉是:

是不是数据库连接泄漏了?

于是我做了这些操作:

1️⃣ 开启连接泄漏检测

remove-abandoned:trueremove-abandoned-timeout:180log-abandoned:true

2️⃣ 开启连接保活

test-while-idle:truevalidation-query:SELECT 1time-between-eviction-runs-millis:60000

结果:

❌ 问题依旧存在
❌ 没有明显泄漏日志


三、进一步排查

1️⃣ 查看数据库连接数

showglobalstatuslike'Threads_connected';

发现:

  • 服务启动前:241
  • 启动后:271

只增加了 30 个连接。

说明:

不是连接无限增长型泄漏


2️⃣ 查看正在执行的 SQL

showprocesslist;

发现大量相同 SQL:

  • 状态:Sending data
  • 执行时间:2000+ 秒
  • 同一条 SQL 被并发执行

而且:

最长执行时间超过 40 分钟还未结束。

问题开始清晰。


四、真正原因

核心问题不是连接泄漏。

而是:

慢 SQL 长时间占用数据库连接,导致连接池被耗尽。

问题 SQL 结构(核心片段)

andnot(dpg<=CASE...AND(SELECTSUM(t2.drp)FROMwxddz_r_202602 t2WHEREt2.adz=t1.adzANDt2.ecd=t1.ecdANDt2.tm>DATE_SUB(t1.tm,INTERVAL24HOUR)ANDt2.tm<=t1.tm)<=CASE...)

这是一个:

相关子查询(Correlated Subquery)

含义是:

  • 外层扫描一行
  • 内层子查询再执行一次

如果外层扫描 10 万行:

👉 内层子查询就执行 10 万次
👉 每次还可能扫描大量数据

这是指数级性能灾难。


五、连锁反应机制

整个问题的完整链路是:

1️⃣ SQL 执行时间极长(40分钟)
2️⃣ 连接一直被占用
3️⃣ 连接池 maxActive 很小(如 6)
4️⃣ 新请求无法获取连接
5️⃣ 30秒后超时
6️⃣ 报 Failed to obtain JDBC Connection
7️⃣ 由于数据库疯狂扫表
8️⃣ CPU 被打满

这不是连接不释放。

而是:

连接被“合法地”长时间占用。


六、为什么 CPU 会爆满?

MySQL 状态显示:

Sending data

这通常意味着:

  • 正在做大量数据扫描
  • 可能 using temporary
  • 可能 using filesort
  • 没有命中索引

如果是全表扫描 + 子查询循环扫描:

数据库 CPU 会持续 100%。


七、根本优化方案

方案一:加复合索引(必要)

如果没有如下索引:

ALTERTABLEwxddz_r_202602ADDINDEXidx_adz_ecd_tm(adz,ecd,tm);

子查询必定全表扫。

这是第一步。


方案二:避免相关子查询

相关子查询是性能杀手。

优化思路:

  • 先汇总 24 小时数据
  • 再 JOIN
  • 或改为分批处理
  • 或程序层面计算

在 MySQL5.7 没有窗口函数的情况下:

可以改为临时汇总表。


方案三:分批处理

原 SQL:

WHEREt1.id>9062999ANDt1.id<9076452

如果数据量大:

建议:

  • 分批 1000 条
  • 逐批计算
  • 控制并发

不要一次性大范围扫描。


方案四:限制定时任务并发

如果是 Quartz 任务:

@DisallowConcurrentExecution

避免同一任务并发执行。

否则慢任务未完成,新任务又启动。


八、数据库参数是否有帮助?

比如:

max_connections=400

是否有用?

答案:

❌ 没本质帮助

如果慢 SQL 不解决:

  • 400 个连接 = 400 个慢查询
  • 数据库更快崩溃

根因不在连接数。


九、事故总结

这次问题本质是:

规则计算型 SQL 被写成在线实时查询
且使用相关子查询导致指数级性能问题

最终表现为:

  • 连接池耗尽
  • JDBC 获取失败
  • 服务不可用
  • CPU 爆满

十、经验总结(非常重要)

1️⃣ 出现 JDBC Connection is not available

不要第一时间怀疑连接泄漏。

先做:

showprocesslist;

看是否有长时间 SQL。


2️⃣ 相关子查询慎用

结构像:

select...whereexists(select...)

在大表中极易出问题。


3️⃣ 定时任务必须控制并发

慢任务叠加是灾难。


4️⃣ 数据规则计算应尽量:

  • 批处理
  • 预汇总
  • 离线计算

不要在线复杂聚合。


最终结论

这次问题不是连接池问题。
不是 max_connections 问题。
不是连接泄漏问题。

而是:

一条极慢 SQL 长时间占用连接,导致连接池耗尽。

当你看到:

Failed to obtain JDBC Connection

请优先排查:

是否存在长时间执行的慢 SQL。

http://www.jsqmd.com/news/417477/

相关文章:

  • 2026最新精装房装修企业优选指南 五大品质品牌参考 - 十大品牌榜
  • 2026年适合小规模企业的五款高效财务软件推荐 - 速递信息
  • Delphi cxgrid设置OnFocusedRecordChanged 事件导致内存泄露.
  • 年游客破300万!文旅灯光如何激活千年古桥的夜经济? - 速递信息
  • P15441 [蓝桥杯 2025 国 Python/Java 研究生组] 耗时最短的路径
  • Vue3 Hooks 对比 Vue2 Mixins 两者之间的区别?
  • 2026年香薰市场风向标:哪些蜡烛OEM公司值得关注,香薰纸片/天然植物精油香氛/别墅香氛,香薰ODM公司推荐排行榜 - 品牌推荐师
  • 简单理解:文档类型doc 和 docx的区别
  • 工业脱碳:Calderion、WenCo和Terravent投资Graforce,推动等离子体热解技术全球规模化应用
  • 2026天津国际高中哪家强?5所热门学校与升学率高的国际高中推荐 - 品牌2025
  • 2026金华义乌AI优化服务商TOP4权威评测:品牌智能化增长优选指南 - 呼呼拉呼
  • 2026年推荐治疗心脏瓣膜疾病的医院参考 - 品牌排行榜
  • Spring全家桶全彩学习进阶笔记(终极版)
  • 《百度最新财报:2025年营收1291亿元 四季度AI业务收入占比43%》
  • 电天下搜索列表数据接口深度实战:AI搜索协议+会员权限+电力数据合规方案
  • Black Hat Asia 2026将揭晓有关人工智能威胁与供应链漏洞的突破性研究成果
  • impression?
  • 2026年天津国际高中推荐汇总,天津国际高中怎么选及比较知名的天津国际高中一览 - 品牌2025
  • 专科生收藏!千笔,口碑爆棚的AI论文网站
  • 工正主流RIP适配UV导带机推荐,有哪些优势? - 工业品网
  • 2026推荐上海主动脉夹层治疗的医院有哪些? - 品牌排行榜
  • 2026年逆流式冷却塔填料/浊环水循环/网格填料/网格板厂家优选: 济源市灵辉环保科技专注工业冷却核心组件 - 品牌推荐官
  • 总结北京瓷砖品牌,哪家瓷砖定制厂家的服务和性价比更高? - 工业推荐榜
  • 【软件】NFS部署
  • 可靠流延机专业制造商有哪些,该如何进行选购和对比 - myqiye
  • GAMES202课程资源
  • Rust 编程实战练习
  • 分析慢走丝机床品牌,为你推荐性价比高的厂家 - 工业设备
  • 2026食用面碱优质品牌揭秘,市面上头部食用纯碱公司推荐排行榜,小酥肉淀粉/超级生粉,食用面碱供应商推荐榜单 - 品牌推荐师
  • ubuntu 可以通过终端命令直接给串口发生数据吗