外观
PostgreSQL 连接数告警
连接数监控配置
1. 使用内置视图监控连接数
sql
-- 查看当前连接数统计
SELECT
datname,
usename,
application_name,
state,
count(*) AS connection_count
FROM
pg_stat_activity
GROUP BY
datname, usename, application_name, state
ORDER BY
connection_count DESC;
-- 查看总连接数和使用率
SELECT
current_setting('max_connections')::int AS max_connections,
COUNT(*) AS current_connections,
ROUND(COUNT(*) * 100.0 / current_setting('max_connections')::int, 2) AS connection_usage_percent
FROM
pg_stat_activity;
-- 查看空闲连接超过5分钟的连接
SELECT
pid,
datname,
usename,
application_name,
client_addr,
backend_start,
state_change
FROM
pg_stat_activity
WHERE
state = 'idle'
AND state_change < NOW() - INTERVAL '5 minutes';2. 使用 Prometheus 监控连接数
配置 Prometheus 抓取 PostgreSQL 连接数指标:
yaml
# prometheus.yml 配置示例
scrape_configs:
- job_name: 'postgresql'
static_configs:
- targets: ['postgres-exporter:9187']
metrics_path: /metrics
scrape_interval: 15s常用的 PostgreSQL 连接数指标:
pg_stat_database_numbackends:每个数据库的连接数pg_settings_max_connections:最大连接数配置pg_stat_activity_count_by_state:按状态分类的连接数
连接数告警配置
1. 使用 Prometheus Alertmanager 配置告警
yaml
# 连接数告警规则示例
groups:
- name: postgresql_connection_alerts
rules:
- alert: PostgreSQLHighConnectionUsage
expr: pg_stat_database_numbackends / pg_settings_max_connections > 0.8
for: 5m
labels:
severity: warning
annotations:
summary: "PostgreSQL 连接使用率过高"
description: "数据库 {{ $labels.datname }} 连接使用率超过 80%,当前值: {{ $value | printf "%.2f" }}%"
- alert: PostgreSQLCriticalConnectionUsage
expr: pg_stat_database_numbackends / pg_settings_max_connections > 0.95
for: 2m
labels:
severity: critical
annotations:
summary: "PostgreSQL 连接使用率严重过高"
description: "数据库 {{ $labels.datname }} 连接使用率超过 95%,当前值: {{ $value | printf "%.2f" }}%"
- alert: PostgreSQLTooManyIdleConnections
expr: sum by (datname) (pg_stat_activity_count_by_state{state="idle"}) > 50
for: 10m
labels:
severity: warning
annotations:
summary: "PostgreSQL 空闲连接过多"
description: "数据库 {{ $labels.datname }} 空闲连接数超过 50,当前值: {{ $value }}"2. 使用脚本监控和告警
创建连接数监控脚本 check_connection_count.sh:
bash
#!/bin/bash
# PostgreSQL 连接数监控脚本
PG_HOST="localhost"
PG_PORT="5432"
PG_USER="postgres"
PG_DB="postgres"
# 最大连接数阈值
WARNING_THRESHOLD=80
CRITICAL_THRESHOLD=95
# 获取当前连接数和最大连接数
CURRENT_CONNECTIONS=$(psql -h $PG_HOST -p $PG_PORT -U $PG_USER -d $PG_DB -t -c "SELECT COUNT(*) FROM pg_stat_activity;")
MAX_CONNECTIONS=$(psql -h $PG_HOST -p $PG_PORT -U $PG_USER -d $PG_DB -t -c "SHOW max_connections;")
# 计算连接使用率
CONNECTION_USAGE=$(echo "scale=2; $CURRENT_CONNECTIONS * 100 / $MAX_CONNECTIONS" | bc)
# 发送告警
if (( $(echo "$CONNECTION_USAGE > $CRITICAL_THRESHOLD" | bc -l) )); then
echo "CRITICAL: PostgreSQL 连接使用率过高 - $CONNECTION_USAGE%"
# 发送紧急告警(如短信、钉钉)
./send_dingtalk.sh "PostgreSQL 连接使用率告警" "数据库连接使用率达到 ${CONNECTION_USAGE}%,已超过临界阈值 ${CRITICAL_THRESHOLD}%"
exit 2
elif (( $(echo "$CONNECTION_USAGE > $WARNING_THRESHOLD" | bc -l) )); then
echo "WARNING: PostgreSQL 连接使用率过高 - $CONNECTION_USAGE%"
# 发送警告告警(如邮件)
./send_email.sh "PostgreSQL 连接使用率告警" "数据库连接使用率达到 ${CONNECTION_USAGE}%,已超过警告阈值 ${WARNING_THRESHOLD}%" "admin@example.com"
exit 1
else
echo "OK: PostgreSQL 连接使用率正常 - $CONNECTION_USAGE%"
exit 0
fi连接数优化配置
1. 调整最大连接数
sql
-- 查看当前配置
SHOW max_connections;
-- 修改最大连接数(需要重启 PostgreSQL 生效)
ALTER SYSTEM SET max_connections = '1000';
-- 修改超级用户预留连接数
ALTER SYSTEM SET superuser_reserved_connections = '10';2. 配置连接池
使用连接池(如 PgBouncer、Pgpool-II)可以有效管理连接数:
ini
# PgBouncer 配置示例(pgbouncer.ini)
[databases]
* = host=localhost port=5432
[pgbouncer]
listen_addr = *
listen_port = 6432
auth_type = md5
auth_file = /etc/pgbouncer/userlist.txt
pool_mode = transaction
max_client_conn = 2000
default_pool_size = 20
min_pool_size = 5
reserve_pool_size = 10
reserve_pool_timeout = 5.03. 配置连接超时
sql
-- 设置 TCP 保持连接参数
ALTER SYSTEM SET tcp_keepalives_idle = '60';
ALTER SYSTEM SET tcp_keepalives_interval = '10';
ALTER SYSTEM SET tcp_keepalives_count = '6';
-- 设置连接空闲超时(需要连接池支持)
-- 对于 PgBouncer,可以在配置文件中设置
-- server_idle_timeout = 3600连接数告警最佳实践
1. 合理设置告警阈值
- 警告阈值:建议设置为最大连接数的 80%,给运维人员足够的响应时间
- 临界阈值:建议设置为最大连接数的 95%,触发紧急告警
- 空闲连接阈值:根据业务场景设置,一般建议 50-100 个
2. 告警发送策略
- 警告级别:连接使用率超过 80% 时,发送邮件告警
- 临界级别:连接使用率超过 95% 时,发送多渠道告警(邮件、短信、钉钉)
- 告警频率:警告级别每 30 分钟发送一次,临界级别每 5 分钟发送一次
3. 连接数优化建议
- 使用连接池:所有应用都应通过连接池访问数据库
- 限制单应用连接数:为每个应用设置最大连接数限制
- 及时释放空闲连接:配置合理的连接超时时间
- 监控连接泄漏:定期检查长时间空闲的连接
- 优化应用代码:减少连接占用时间,避免长事务
4. 定期审查连接数配置
- 每季度审查一次最大连接数配置
- 根据业务增长趋势调整连接数限制
- 定期分析连接数使用模式,优化连接池配置
常见问题(FAQ)
Q1:如何查看 PostgreSQL 当前连接数?
A1:可以使用以下命令查看当前连接数:
sql
-- 查看总连接数
SELECT COUNT(*) FROM pg_stat_activity;
-- 查看详细的连接分布
SELECT
datname,
usename,
application_name,
state,
count(*) AS connection_count
FROM
pg_stat_activity
GROUP BY
datname, usename, application_name, state;Q2:如何设置合理的最大连接数?
A2:设置最大连接数需要考虑:
- 服务器硬件资源(CPU、内存)
- 每个连接的内存占用(shared_buffers、work_mem 等)
- 业务并发需求
- 连接池配置
计算公式参考:
max_connections = (系统可用内存 - 操作系统和其他服务占用内存) / 每个连接所需内存Q3:如何处理连接数达到上限的情况?
A3:处理连接数达到上限的方法:
- 检查是否有连接泄漏,终止长时间空闲的连接
- 临时增加最大连接数(如果服务器资源允许)
- 优化应用代码,减少连接占用时间
- 调整连接池配置,降低连接数
- 考虑水平扩展,增加数据库实例
Q4:如何自动终止空闲连接?
A4:可以使用以下方法自动终止空闲连接:
- 使用
pg_stat_activate扩展自动终止空闲连接 - 创建定时任务,定期执行终止空闲连接的 SQL:
sql
-- 终止空闲超过10分钟的连接
SELECT pg_terminate_backend(pid)
FROM pg_stat_activity
WHERE state = 'idle'
AND state_change < NOW() - INTERVAL '10 minutes';- 在连接池中配置空闲连接超时
Q5:如何监控连接池的性能?
A5:监控连接池性能的方法:
- 监控连接池的连接使用率、等待队列长度
- 监控连接获取时间和连接创建时间
- 监控连接池的错误日志,如连接拒绝、连接超时
- 使用连接池提供的监控指标(如 PgBouncer 的
stats管理接口)
Q6:如何预防连接数告警?
A6:预防连接数告警的方法:
- 合理规划数据库架构,避免单点压力
- 使用连接池管理连接
- 定期监控连接数使用情况
- 根据业务增长提前调整连接数配置
- 优化应用代码,减少连接占用
- 实施连接数限流策略
