数据访问诊断总览
数据访问故障常被归到「数据库慢」,但 Java 侧的问题多发生在连接池和事务边界上。连接池耗尽既可能来自数据库慢查询,也可能来自事务持有过长、线程池拥塞或连接未归还。本目录把数据访问的排障入口单列,强调跨层证据链。
两条主线
- 连接池耗尽案例:获取连接超时、连接泄漏、慢 SQL 引发的资源占用。重点区分「连接需求超过供给」和「连接被持有不放」。
- 慢 SQL 案例:执行计划变化、锁等待、数据库耗时与应用耗时不一致。重点判断慢在数据库还是应用侧。
连接池耗尽的跨层归因
连接池是一个把「应用并发」和「数据库承载能力」隔开的缓冲层。它耗尽时,根因很少只在池本身。
| 你观察到的信号 | 更可能的根因层 | 下一步入口 |
|---|---|---|
| 活跃连接数打满、等待线程堆积 | 数据库慢查询占住连接 | 慢 SQL 案例 |
| 活跃连接数打满、事务持有时间长 | 事务边界过大或连接未归还 | 并发诊断:异步超时 |
| 活跃连接数打满、上游线程池也满 | 上游拥塞传导到数据访问 | 并发诊断总论 |
| 连接泄漏缓慢增长、fd 上升 | 异常路径未关闭连接 | 网络案例:连接泄漏 |
不要把连接池耗尽直接当成「数据库不行」。先确认连接是被慢查询占住、被事务持有,还是根本没归还池,再决定去数据库还是回应用层。
慢 SQL 的归属判断
应用日志报的 SQL 耗时和数据库自身看到的执行耗时未必一致。差异往往来自网络往返、驱动批处理、连接等待或事务包裹。判断归属时先看「等待获取连接的时间」和「真正执行的时间」是否混在一起。
使用方式
- 记录现象、时间点和影响范围,先不猜根因。
- 用连接池指标(活跃数、等待数、等待时间)定位是「供给」还是「持有」问题。
- 拿到 SQL 执行计划与锁信息后,再判断慢在数据库还是应用。
- 修复后同时验证连接池指标恢复、SQL 耗时下降和业务结果正常。