外观
PostgreSQL 数据库级别指标
PostgreSQL 数据库级别指标是数据库监控的核心,包括连接数、事务指标、查询性能、缓存命中率等。这些指标直接反映数据库的运行状态和性能表现,是DBA进行性能优化和故障排查的重要依据。
数据库级别指标类型
1. 连接数指标
- 总连接数:当前数据库的总连接数
- 活跃连接数:当前正在执行查询的连接数
- 空闲连接数:当前空闲的连接数
- 等待连接数:等待获取连接的连接数
- 最大连接数:数据库允许的最大连接数
- 连接使用率:当前连接数与最大连接数的比值
2. 事务指标
- 事务提交数:每秒提交的事务数量(TPS)
- 事务回滚数:每秒回滚的事务数量
- 事务成功率:提交事务数与总事务数的比值
- 长事务数量:运行时间超过阈值的事务数量
- 长事务平均运行时间:长事务的平均运行时间
3. 查询性能指标
- 查询次数:每秒执行的查询数量(QPS)
- 慢查询数:每秒执行的慢查询数量
- 平均查询响应时间:所有查询的平均响应时间
- 查询计划命中率:计划缓存的命中率
- 临时文件使用率:查询生成的临时文件数量
4. 缓存指标
- 共享缓冲区命中率:共享缓冲区的命中率
- 工作内存使用率:工作内存的使用率
- 计划缓存命中率:计划缓存的命中率
- 操作系统缓存命中率:操作系统缓存的命中率
- 有效缓存命中率:共享缓冲区和操作系统缓存的综合命中率
5. 锁指标
- 锁数量:当前数据库中的锁数量
- 等待锁的查询数:等待获取锁的查询数量
- 锁等待时间:查询等待锁的平均时间
- 死锁数量:发生死锁的数量
指标收集方法
1. 内置视图查询
PostgreSQL 提供了丰富的内置视图,可以直接查询各种数据库级别指标。
sql
-- 1. 查询连接数指标
SELECT
count(*) AS total_connections,
sum(CASE WHEN state = 'active' THEN 1 ELSE 0 END) AS active_connections,
sum(CASE WHEN state = 'idle' THEN 1 ELSE 0 END) AS idle_connections,
(SELECT setting::int FROM pg_settings WHERE name = 'max_connections') AS max_connections,
round(100.0 * count(*) / (SELECT setting::int FROM pg_settings WHERE name = 'max_connections'), 2) AS connection_usage_percent
FROM pg_stat_activity;
-- 2. 查询事务指标
SELECT
datname,
xact_commit AS transactions_committed,
xact_rollback AS transactions_rolled_back,
round(100.0 * xact_commit / nullif(xact_commit + xact_rollback, 0), 2) AS transaction_success_rate
FROM pg_stat_database
WHERE datname NOT IN ('template0', 'template1');
-- 3. 查询查询性能指标
SELECT
datname,
tup_returned AS tuples_returned,
tup_fetched AS tuples_fetched,
tup_inserted AS tuples_inserted,
tup_updated AS tuples_updated,
tup_deleted AS tuples_deleted,
blks_read AS blocks_read,
blks_hit AS blocks_hit,
round(100.0 * blks_hit / nullif(blks_hit + blks_read, 0), 2) AS buffer_hit_ratio
FROM pg_stat_database
WHERE datname NOT IN ('template0', 'template1');
-- 4. 查询长事务
SELECT
pid,
datname,
usename,
application_name,
client_addr,
state,
query_start,
now() - query_start AS duration,
query
FROM pg_stat_activity
WHERE state = 'active'
AND now() - query_start > INTERVAL '5 minutes'
ORDER BY duration DESC;
-- 5. 查询锁信息
SELECT
locktype,
database,
relation::regclass,
mode,
granted,
pid,
usename,
query
FROM pg_locks
JOIN pg_stat_activity ON pg_locks.pid = pg_stat_activity.pid
WHERE NOT granted
ORDER BY query_start;2. 扩展工具
使用 PostgreSQL 扩展工具收集更详细的数据库级别指标。
pg_stat_statements
sql
-- 1. 安装扩展
CREATE EXTENSION pg_stat_statements;
-- 2. 配置参数
ALTER SYSTEM SET shared_preload_libraries = 'pg_stat_statements';
ALTER SYSTEM SET pg_stat_statements.track = 'all';
ALTER SYSTEM SET pg_stat_statements.max = 10000;
ALTER SYSTEM SET pg_stat_statements.track_utility = 'on';
-- 3. 查询慢查询
SELECT
queryid,
query,
calls,
total_time,
mean_time,
rows,
100.0 * shared_blks_hit / nullif(shared_blks_hit + shared_blks_read, 0) AS hit_percent
FROM pg_stat_statements
ORDER BY mean_time DESC
LIMIT 10;pg_stat_monitor
sql
-- 1. 安装扩展(需要从PGDG仓库安装)
-- yum install postgresql14-pg-stat-monitor
-- 2. 配置参数
ALTER SYSTEM SET shared_preload_libraries = 'pg_stat_monitor';
ALTER SYSTEM SET pg_stat_monitor.pgsm_max = 10000;
ALTER SYSTEM SET pg_stat_monitor.pgsm_track = 'all';
-- 3. 查询监控数据
SELECT
query,
calls,
total_time,
min_time,
max_time,
mean_time,
rows
FROM pg_stat_monitor
ORDER BY total_time DESC
LIMIT 10;3. 监控工具
使用专业监控工具收集和分析数据库级别指标。
Prometheus + PostgreSQL Exporter
yaml
# 1. PostgreSQL Exporter 配置
# 下载并安装 PostgreSQL Exporter
wget https://github.com/prometheus-community/postgres_exporter/releases/download/v0.14.0/postgres_exporter-0.14.0.linux-amd64.tar.gz
tar xvfz postgres_exporter-0.14.0.linux-amd64.tar.gz
cd postgres_exporter-0.14.0.linux-amd64
# 2. 创建数据库用户和配置
CREATE USER postgres_exporter WITH PASSWORD 'password';
GRANT CONNECT ON DATABASE postgres TO postgres_exporter;
GRANT SELECT ON pg_stat_database TO postgres_exporter;
# 3. 启动 PostgreSQL Exporter
export DATA_SOURCE_NAME="postgresql://postgres_exporter:password@localhost:5432/postgres?sslmode=disable"
./postgres_exporter
# 4. Prometheus 配置
scrape_configs:
- job_name: 'postgres'
static_configs:
- targets: ['localhost:9187']
scrape_interval: 15s关键指标监控
1. 连接数监控
sql
-- 1. 查看当前连接数
SELECT count(*) FROM pg_stat_activity;
-- 2. 查看连接状态分布
SELECT state, count(*) FROM pg_stat_activity GROUP BY state;
-- 3. 监控连接使用率的告警设置
-- 当连接使用率超过 80% 时触发告警
-- Prometheus 告警规则示例
ALERT HighConnectionUsage
IF (sum by(instance) (pg_stat_activity_count{datname!~"template.*"}) / pg_settings_max_connections * 100) > 80
FOR 5m
LABELS { severity="warning" }
ANNOTATIONS {
summary = "High connection usage on {{ $labels.instance }}",
description = "Connection usage is {{ $value }}% for 5 minutes"
}2. 事务监控
sql
-- 1. 查看事务提交和回滚率
SELECT
datname,
xact_commit,
xact_rollback,
round(100.0 * xact_rollback / nullif(xact_commit + xact_rollback, 0), 2) AS rollback_rate
FROM pg_stat_database
WHERE datname NOT IN ('template0', 'template1');
-- 2. 监控事务回滚率的告警设置
-- 当事务回滚率超过 10% 时触发告警
-- Prometheus 告警规则示例
ALERT HighTransactionRollbackRate
IF (sum by(instance, datname) (rate(pg_stat_database_xact_rollback[5m])) / sum by(instance, datname) (rate(pg_stat_database_xact_commit[5m]) + rate(pg_stat_database_xact_rollback[5m]))) * 100 > 10
FOR 5m
LABELS { severity="warning" }
ANNOTATIONS {
summary = "High transaction rollback rate on {{ $labels.instance }} {{ $labels.datname }}",
description = "Transaction rollback rate is {{ $value }}% for 5 minutes"
}3. 缓存命中率监控
sql
-- 1. 查看共享缓冲区命中率
SELECT
datname,
round(100.0 * blks_hit / nullif(blks_hit + blks_read, 0), 2) AS buffer_hit_ratio
FROM pg_stat_database
WHERE datname NOT IN ('template0', 'template1');
-- 2. 监控缓存命中率的告警设置
-- 当缓存命中率低于 95% 时触发告警
-- Prometheus 告警规则示例
ALERT LowBufferHitRatio
IF (sum by(instance, datname) (rate(pg_stat_database_blks_hit[5m])) / sum by(instance, datname) (rate(pg_stat_database_blks_hit[5m]) + rate(pg_stat_database_blks_read[5m]))) * 100 < 95
FOR 5m
LABELS { severity="warning" }
ANNOTATIONS {
summary = "Low buffer hit ratio on {{ $labels.instance }} {{ $labels.datname }}",
description = "Buffer hit ratio is {{ $value }}% for 5 minutes"
}4. 慢查询监控
sql
-- 1. 查看慢查询日志配置
SHOW log_min_duration_statement;
-- 2. 启用慢查询日志
ALTER SYSTEM SET log_min_duration_statement = '1000ms';
-- 3. 查看慢查询
SELECT
pid,
datname,
usename,
application_name,
client_addr,
query_start,
now() - query_start AS duration,
query
FROM pg_stat_activity
WHERE state = 'active'
AND now() - query_start > INTERVAL '1 second'
ORDER BY duration DESC;
-- 4. 监控慢查询的告警设置
-- 当慢查询数超过 5 个时触发告警
-- Prometheus 告警规则示例
ALERT HighSlowQueryCount
IF sum by(instance, datname) (rate(pg_stat_database_conflicts[5m])) > 5
FOR 5m
LABELS { severity="warning" }
ANNOTATIONS {
summary = "High slow query count on {{ $labels.instance }} {{ $labels.datname }}",
description = "Slow query count is {{ $value }} for 5 minutes"
}最佳实践
1. 生产环境监控建议
- 设置合理的告警阈值:根据业务需求和系统配置设置合适的告警阈值
- 监控关键指标:重点监控连接数、事务指标、缓存命中率、慢查询等关键指标
- 建立基线:建立正常运行时的指标基线,便于识别异常情况
- 定期分析监控数据:定期分析历史监控数据,识别性能趋势和潜在问题
- 配置多级别告警:根据问题严重程度设置不同级别的告警
2. 性能优化建议
sql
-- 1. 连接数优化
-- 调整最大连接数
ALTER SYSTEM SET max_connections = '200';
-- 配置连接池
-- 使用 PgBouncer 或 Odyssey 等连接池工具
-- 2. 内存配置优化
-- 调整共享缓冲区大小(建议为系统内存的 25-30%)
ALTER SYSTEM SET shared_buffers = '4GB';
-- 调整工作内存
ALTER SYSTEM SET work_mem = '16MB';
-- 调整 maintenance 工作内存
ALTER SYSTEM SET maintenance_work_mem = '512MB';
-- 3. 事务优化
-- 避免长事务
-- 合理使用事务隔离级别
-- 及时提交或回滚事务
-- 4. 查询优化
-- 优化慢查询语句
-- 合理创建索引
-- 使用 EXPLAIN ANALYZE 分析查询计划3. 监控工具选择
| 工具名称 | 适用场景 | 优点 | 缺点 |
|---|---|---|---|
| Prometheus + PostgreSQL Exporter | 大规模分布式环境 | 开源、灵活、强大的查询语言 | 需要手动配置告警规则 |
| pgAdmin | 单实例监控 | 官方工具、易于使用 | 功能相对简单 |
| Datadog | 云原生环境 | 易于部署、强大的分析功能 | 商业化产品,成本高 |
| New Relic | 应用性能监控 | 与应用深度集成 | 专注于应用监控 |
| Zabbix | 企业级监控 | 全面的监控功能 | 配置复杂、资源消耗大 |
常见问题处理
1. 连接数过多
问题:数据库连接数达到最大限制,新连接无法建立
解决方法:
- 增加最大连接数配置
- 优化应用程序,减少不必要的连接
- 使用连接池工具,如 PgBouncer 或 Odyssey
- 关闭空闲连接
2. 事务回滚率过高
问题:事务回滚率过高,影响数据库性能
解决方法:
- 检查应用程序代码,找出导致事务回滚的原因
- 优化事务逻辑,减少事务冲突
- 合理设置事务隔离级别
- 增加死锁检测频率
3. 缓存命中率过低
问题:数据库缓存命中率过低,导致大量磁盘 I/O
解决方法:
- 增加 shared_buffers 配置
- 优化查询,减少磁盘 I/O 操作
- 考虑使用 SSD 存储
- 分析缓存使用情况,找出缓存未命中的原因
4. 慢查询过多
问题:数据库中存在大量慢查询,影响整体性能
解决方法:
- 启用慢查询日志,找出慢查询语句
- 使用 EXPLAIN ANALYZE 分析查询计划
- 优化查询语句,添加必要的索引
- 考虑使用查询重写或物化视图
常见问题(FAQ)
Q1:如何确定数据库级指标的正常范围?
A1:数据库级指标的正常范围取决于数据库配置和业务负载,需要:
- 建立基线:在数据库正常运行时收集指标数据,建立基线
- 参考行业标准:如共享缓冲区命中率一般应高于 95%,连接使用率应低于 80%
- 根据业务需求调整:不同业务对数据库性能的要求不同
Q2:如何监控 PostgreSQL 数据库的连接数?
A2:可以使用以下方法监控连接数:
- 查询 pg_stat_activity 视图
- 使用监控工具如 Prometheus + PostgreSQL Exporter
- 配置连接数告警
Q3:如何优化 PostgreSQL 数据库的缓存命中率?
A3:可以采取以下措施:
- 增加 shared_buffers 配置
- 优化查询,减少磁盘 I/O 操作
- 合理设置 work_mem 配置
- 考虑使用 SSD 存储
Q4:如何处理 PostgreSQL 中的长事务?
A4:处理长事务可以采取以下措施:
- 识别长事务:使用 pg_stat_activity 视图查询长事务
- 分析长事务原因:检查应用程序代码,找出导致长事务的原因
- 优化事务逻辑:将长事务拆分为多个短事务
- 设置事务超时:配置 idle_in_transaction_session_timeout 参数
Q5:如何监控 PostgreSQL 中的慢查询?
A5:监控慢查询可以采取以下措施:
- 启用慢查询日志:设置 log_min_duration_statement 参数
- 使用 pg_stat_statements 扩展:收集和分析慢查询
- 使用专业监控工具:如 Prometheus + PostgreSQL Exporter
- 配置慢查询告警:当慢查询数超过阈值时触发告警
Q6:pg_stat_statements 和 pg_stat_monitor 有什么区别?
A6:主要区别如下:
- pg_stat_statements 是 PostgreSQL 官方扩展,稳定性更好
- pg_stat_monitor 提供更丰富的监控指标,如查询执行计划、绑定变量信息
- pg_stat_monitor 支持查询采样和统计信息的聚合
- pg_stat_monitor 对高并发环境的性能影响更小
Q7:如何优化 PostgreSQL 数据库的事务性能?
A7:优化事务性能可以采取以下措施:
- 避免长事务
- 合理设置事务隔离级别
- 及时提交或回滚事务
- 减少事务中的锁竞争
- 考虑使用乐观锁机制
Q8:如何监控 PostgreSQL 数据库的锁情况?
A8:监控锁情况可以采取以下措施:
- 查询 pg_locks 视图
- 使用 pg_stat_activity 视图关联查询锁信息
- 配置锁等待告警:当锁等待时间超过阈值时触发告警
- 使用专业监控工具:如 Prometheus + PostgreSQL Exporter
