3. 连接池水位定义
连接池水位是衡量数据库连接池中活跃连接、空闲连接与等待请求之间动态平衡的核心指标。它直接反映了系统当前承受的并发压力以及连接资源的利用效率。理解水位概念,是进行连接池调优的前提。
3.1 什么是连接池水位
连接池水位借鉴了“水库水位”的比喻:连接池中的连接总数相当于水库的总库容,正在被使用的连接(活跃连接)相当于当前水位。水位的高低由并发请求的吞吐量和连接释放速度共同决定。
核心公式:
当前水位 = 活跃连接数 / 最大连接数 × 100%
空闲水位 = 空闲连接数 / 最大连接数 × 100%
当前水位 = 活跃连接数 / 最大连接数 × 100%
空闲水位 = 空闲连接数 / 最大连接数 × 100%
当水位持续上升时,意味着系统正在承受更高的并发压力;当水位接近或超过设计阈值时,系统可能进入过载状态,导致请求排队、超时甚至拒绝服务。
3.2 水位高低对系统的影响
连接池水位的高低直接影响数据库系统的吞吐量、响应时间和稳定性。不同水位区间对应不同的系统行为特征:
| 水位区间 | 系统状态 | 响应时间 | 资源消耗 | 风险等级 |
|---|---|---|---|---|
| 低水位(0% ~ 40%) | 空闲充足 | 极快(< 1ms 获取连接) | 低 | 安全 |
| 中水位(40% ~ 70%) | 正常负载 | 正常(1~5ms 获取连接) | 中等 | 正常 |
| 高水位(70% ~ 90%) | 高负载 | 变慢(5~20ms 获取连接) | 较高 | 警告 |
| 临界水位(90% ~ 100%) | 过载 | 显著变慢(20ms+ 或超时) | 极高 | 危险 |
| 溢出水位(≥100%) | 拒绝服务 | 请求排队或直接失败 | 峰值 | 严重 |
水位过高的连锁反应:
当连接池水位持续处于高水位以上时,不仅新请求需要排队等待连接,已持有的连接也可能因为等待数据库响应而长时间不释放,形成“连接饥饿”的恶性循环。严重时会导致数据库连接数打满,应用层出现大量
当连接池水位持续处于高水位以上时,不仅新请求需要排队等待连接,已持有的连接也可能因为等待数据库响应而长时间不释放,形成“连接饥饿”的恶性循环。严重时会导致数据库连接数打满,应用层出现大量
org.postgresql.util.PSQLException: FATAL: sorry, too many clients already 错误。
3.3 水位的三个关键阈值
在实际运维中,我们通常定义三个关键水位阈值来指导监控和调优决策:
3.3.1 低水位(Low Watermark)
低水位是连接池中空闲连接数量的下限阈值。当空闲连接数低于此阈值时,连接池可以提前创建新连接(预热),以应对即将到来的请求高峰。
- 典型值:最大连接数的 20% ~ 30%
- 作用:避免突发流量导致连接创建延迟
- 监控指标:
idle_connections < min_idle - 调优方向:如果频繁触发低水位告警,应适当增大
min_idle或max_connections
3.3.2 高水位(High Watermark)
高水位是连接池中活跃连接数的上限预警阈值。当活跃连接数超过此阈值时,系统进入高负载状态,需要触发扩容或限流措施。
- 典型值:最大连接数的 70% ~ 80%
- 作用:提前预警,防止连接池打满
- 监控指标:
active_connections > high_watermark - 调优方向:检查慢查询、长事务,或增加连接池容量
3.3.3 溢出水位(Overflow Watermark)
溢出水位是连接池的绝对容量上限。当活跃连接数达到最大连接数时,新请求无法获取连接,必须排队等待或直接拒绝。
- 典型值:最大连接数的 100%
- 作用:定义系统的最大并发承载能力
- 监控指标:
active_connections == max_connections且pending_requests > 0 - 调优方向:必须扩容(增加
max_connections)或优化应用层连接使用模式
3.4 水位监控的实践要点
监控命令示例:
使用 pg_stat_activity 和 pg_stat_database 实时查看连接池水位:
使用 pg_stat_activity 和 pg_stat_database 实时查看连接池水位:
-- 查看当前活跃连接数及水位百分比
SELECT
count(*) AS total_connections,
count(*) FILTER (WHERE state = 'active') AS active_connections,
round(100.0 * count(*) FILTER (WHERE state = 'active') / current_setting('max_connections')::int, 1) AS active_pct,
round(100.0 * count(*) FILTER (WHERE state = 'idle') / current_setting('max_connections')::int, 1) AS idle_pct
FROM pg_stat_activity
WHERE backend_type = 'client backend';
-- 查看等待连接的请求数(溢出风险)
SELECT count(*) AS waiting_requests
FROM pg_stat_activity
WHERE wait_event_type = 'Lock'
AND state = 'active';