Skip to content

PostgreSQL 监控层次结构

PostgreSQL 监控体系应该覆盖基础设施层、数据库层、应用层三个主要层次。每个层次都有其独特的监控目标和指标,需要使用不同的监控工具和方法。合理的监控层次结构能够帮助运维团队全面了解系统状态,及时发现和定位问题,提高系统的可靠性和可用性。

监控层次结构的设计应该遵循以下原则:

  1. 全面覆盖:确保所有关键组件和指标都被监控
  2. 分层管理:不同层次的监控由不同团队或角色负责
  3. 告警分级:根据影响范围和严重程度设置不同级别的告警
  4. 数据关联:不同层次的监控数据应该能够关联分析,便于定位根因
  5. 可扩展性:监控体系应该能够随着系统规模的增长而扩展

基础设施层监控

基础设施层监控主要关注服务器的硬件资源使用情况,包括 CPU、内存、磁盘 I/O、网络等。这些指标是系统运行的基础,直接影响 PostgreSQL 的性能和稳定性。

CPU 监控

CPU 使用率是衡量系统负载的重要指标。PostgreSQL 是一个 CPU 密集型数据库,尤其是在执行复杂查询和并发操作时。CPU 监控指标包括:

  • 总体 CPU 使用率
  • 用户态 CPU 使用率
  • 系统态 CPU 使用率
  • 等待 I/O 的 CPU 使用率
  • 上下文切换次数
  • 中断次数
bash
# 使用 top 命令查看 CPU 使用率
top -u postgres

# 使用 vmstat 命令查看系统 CPU 状态
vmstat 1

# 使用 mpstat 命令查看每个 CPU 核心的使用率
mpstat -P ALL 1

内存监控

内存是影响 PostgreSQL 性能的关键因素。PostgreSQL 使用 shared_buffers 缓存数据块,使用 work_mem 处理排序和哈希操作。内存监控指标包括:

  • 已用内存
  • 空闲内存
  • 缓存和缓冲区使用情况
  • 交换空间使用情况
  • PostgreSQL 进程的内存使用情况
bash
# 使用 free 命令查看内存使用情况
free -h

# 使用 ps 命令查看 PostgreSQL 进程的内存使用情况
ps aux --sort=-%mem | grep postgres | head -10

# 使用 pmap 命令查看详细的内存映射
pmap -x $(pgrep -f "postgres: postmaster")

磁盘 I/O 监控

磁盘 I/O 是数据库性能的常见瓶颈。PostgreSQL 的数据文件、WAL 文件、临时文件都需要磁盘 I/O 操作。磁盘 I/O 监控指标包括:

  • 磁盘使用率
  • 磁盘 I/O 吞吐量
  • 磁盘 I/O 延迟
  • 磁盘队列长度
  • 读写比例
bash
# 使用 iostat 命令查看磁盘 I/O 状态
iostat -x 1

# 使用 df 命令查看磁盘使用率
df -h

# 使用 du 命令查看 PostgreSQL 数据目录大小
du -sh /var/lib/postgresql/14/main

网络监控

网络监控对于分布式 PostgreSQL 架构至关重要,尤其是在主从复制、读写分离等场景下。网络监控指标包括:

  • 网络吞吐量
  • 网络延迟
  • 网络丢包率
  • 连接数
  • 网络错误数
bash
# 使用 iftop 命令查看网络流量
iftop -i eth0

# 使用 netstat 命令查看网络连接
netstat -an | grep ESTABLISHED

# 使用 ping 命令测试网络延迟
ping -c 10 db.example.com

数据库层监控

数据库层监控是 PostgreSQL 监控的核心,关注数据库内部的运行状态和性能指标。

连接监控

连接数是数据库负载的重要指标,过多的连接会消耗系统资源,影响性能。连接监控指标包括:

  • 当前连接数
  • 最大连接数
  • 连接状态分布
  • 连接来源分布
  • 连接建立速率
sql
-- 查看当前连接状态分布
SELECT
    state,
    count(*) AS count,
    usename,
    application_name
FROM pg_stat_activity
GROUP BY state, usename, application_name
ORDER BY count DESC;

-- 查看连接来源分布
SELECT
    client_addr,
    count(*) AS connections,
    usename,
    application_name
FROM pg_stat_activity
GROUP BY client_addr, usename, application_name
ORDER BY connections DESC;

查询性能监控

查询性能直接影响用户体验,是数据库监控的重点。查询性能监控指标包括:

  • 每秒查询数(QPS)
  • 平均查询执行时间
  • P95/P99 查询执行时间
  • 慢查询数量
  • 查询类型分布
sql
-- 使用 pg_stat_statements 查看查询性能
SELECT
    substring(query, 1, 100) AS query,
    calls,
    round(total_exec_time::numeric, 2) AS total_time,
    round(mean_exec_time::numeric, 2) AS avg_time,
    rows,
    round(100 * shared_blks_hit / NULLIF(shared_blks_hit + shared_blks_read, 0), 2) AS cache_hit_rate
FROM pg_stat_statements
ORDER BY total_exec_time DESC
LIMIT 20;

复制监控

对于主从复制架构,复制状态是确保数据一致性和高可用性的关键。复制监控指标包括:

  • 复制延迟
  • 复制状态
  • WAL 生成速率
  • WAL 应用速率
  • 复制槽状态
sql
-- 查看复制状态
SELECT
    pid,
    application_name,
    client_addr,
    state,
    sent_lsn,
    write_lsn,
    flush_lsn,
    replay_lsn,
    round((pg_wal_lsn_diff(sent_lsn, replay_lsn) / 1024 / 1024)::numeric, 2) AS lag_mb,
    write_lag,
    flush_lag,
    replay_lag,
    sync_priority,
    sync_state
FROM pg_stat_replication;

-- 查看 WAL 接收状态
SELECT
    pid,
    status,
    receive_start_lsn,
    received_lsn,
    last_msg_send_time,
    last_msg_receipt_time,
    latest_end_lsn,
    latest_end_time
FROM pg_stat_wal_receiver;

锁监控

锁等待是导致查询延迟和应用性能下降的常见原因。锁监控指标包括:

  • 锁数量
  • 锁等待时间
  • 锁等待类型
  • 阻塞进程
sql
-- 查看锁等待情况
SELECT
    blocked.pid AS blocked_pid,
    blocked.usename AS blocked_user,
    blocked.query AS blocked_query,
    blocked.state AS blocked_state,
    blocker.pid AS blocker_pid,
    blocker.usename AS blocker_user,
    blocker.query AS blocker_query,
    blocker.state AS blocker_state,
    blocked.wait_event AS blocked_wait,
    blocker.wait_event AS blocker_wait
FROM pg_stat_activity blocked
JOIN pg_stat_activity blocker ON blocker.pid = ANY(pg_blocking_pids(blocked.pid))
WHERE blocked.wait_event IS NOT NULL;

-- 查看锁类型统计
SELECT
    mode,
    locktype,
    database,
    count(*) AS count
FROM pg_locks
WHERE database = (SELECT oid FROM pg_database WHERE datname = current_database())
GROUP BY mode, locktype, database
ORDER BY count DESC;

应用层监控

应用层监控关注数据库对应用的服务质量和影响,包括业务指标和用户体验。

业务指标监控

业务指标直接反映系统的业务价值和用户体验,包括:

  • 每秒事务数(TPS)
  • 成功/失败事务比例
  • 关键业务操作的响应时间
  • 业务错误率
  • 并发用户数
sql
-- 查看事务统计
SELECT
    datname,
    xact_commit,
    xact_rollback,
    round(100 * xact_rollback / NULLIF(xact_commit + xact_rollback, 0), 2) AS rollback_ratio
FROM pg_stat_database
WHERE datname NOT IN ('template0', 'template1');

连接池监控

如果应用使用连接池,连接池的状态也是监控的重要内容:

  • 连接池使用率
  • 活跃连接数
  • 等待连接数
  • 连接创建和关闭速率
  • 连接存活时间
sql
-- 使用 PgBouncer 查看连接池状态
-- 连接到 PgBouncer 的管理数据库
psql -h pgbouncer_host -p 6432 -U pgbouncer pgbouncer

-- 查看连接池状态
SHOW pools;

-- 查看客户端连接
SHOW clients;

-- 查看服务器端连接
SHOW servers;

监控工具整合

为了实现全面的监控,需要整合多种监控工具和数据源。常见的监控工具组合包括:

Prometheus + Grafana

Prometheus 是一个开源的时序数据库,用于存储监控数据。Grafana 是一个开源的数据可视化工具,用于展示监控指标。通过 PostgreSQL Exporter,可以将 PostgreSQL 的监控指标导出到 Prometheus,然后在 Grafana 中创建仪表板进行可视化展示。

yaml
# prometheus.yml 配置示例
scrape_configs:
  - job_name: 'postgresql'
    static_configs:
      - targets: ['localhost:9187']
    metrics_path: /metrics
    relabel_configs:
      - source_labels: [__address__]
        target_label: instance
        regex: '([^:]+):\\d+'
        replacement: '${1}'

Zabbix

Zabbix 是一个功能强大的开源监控系统,支持多种监控方式,包括主动监控、被动监控、JMX 监控等。Zabbix 提供了 PostgreSQL 模板,可以监控 PostgreSQL 的关键指标。

Nagios

Nagios 是一个经典的开源监控系统,用于监控网络设备、服务器和应用程序。Nagios 可以通过插件监控 PostgreSQL 的状态,如 check_pgsql 插件可以检查 PostgreSQL 服务是否正常运行。

自定义监控脚本

除了使用现成的监控工具,还可以编写自定义监控脚本,监控特定的业务指标或系统状态。自定义监控脚本可以使用 Python、Shell 等语言编写,定期执行并将结果发送到监控系统或告警通道。

监控告警策略

监控告警是监控体系的重要组成部分,当指标超过阈值时,及时通知运维团队。告警策略的设计应该遵循以下原则:

告警分级

根据影响范围和严重程度,将告警分为不同级别:

  • 紧急(Emergency):系统已经或即将崩溃,需要立即处理
  • 严重(Critical):关键功能不可用,影响大量用户
  • 警告(Warning):系统出现异常,可能影响服务
  • 信息(Info):系统状态变化,不影响服务

告警收敛

告警收敛是指将多个相关的告警合并为一个,避免告警风暴。告警收敛的方法包括:

  • 基于时间的收敛:同一指标在短时间内的多次告警只发送一次
  • 基于规则的收敛:将相关指标的告警合并为一个
  • 基于拓扑的收敛:根据系统拓扑关系,只发送根因告警

告警通知

告警通知渠道应该多样化,确保告警能够及时送达:

  • 邮件通知:适合非紧急告警
  • 短信通知:适合紧急告警
  • 电话通知:适合非常紧急的告警
  • 即时通讯工具:如企业微信、钉钉等

常见问题(FAQ)

Q1: 如何确定监控指标的告警阈值?

A1: 告警阈值的确定需要基于历史数据和业务需求。首先收集正常运行时的指标数据,计算平均值、标准差、P95、P99 等统计值。然后根据业务容忍度设置阈值:警告阈值可以设置为 P95 或 P99 附近,严重阈值可以设置为 P99+3σ 或业务可接受的上限。建议定期调整阈值,适应系统负载和业务需求的变化。

Q2: 如何处理大量的监控数据?

A2: 处理大量监控数据的方法包括:

  1. 数据采样:降低采样频率,减少数据量
  2. 数据聚合:按时间粒度聚合数据,如将秒级数据聚合为分钟级或小时级
  3. 数据保留策略:设置不同的保留期限,如保留 7 天的原始数据,30 天的聚合数据,1 年的长期趋势数据
  4. 分布式存储:使用分布式数据库存储监控数据,提高查询性能
  5. 数据压缩:对监控数据进行压缩,减少存储空间

Q3: 如何关联不同层次的监控数据?

A3: 关联不同层次的监控数据需要建立统一的时间戳和标识。例如,使用相同的时间戳格式和时区,使用服务器名称或 IP 地址作为标识。在 Grafana 中,可以通过变量和仪表板链接实现不同层次监控数据的关联。在 Prometheus 中,可以使用标签(labels)关联不同指标的数据。

Q4: 如何监控 PostgreSQL 分区表?

A4: 监控分区表需要关注:

  1. 分区数量和大小:确保没有分区过度增长
  2. 查询是否利用分区修剪:通过 EXPLAIN ANALYZE 查看分区信息
  3. 各分区的统计信息:确保 ANALYZE 覆盖所有分区
  4. 跨分区查询的性能:监控跨分区查询的执行时间和资源使用情况

可以为分区表创建专门的监控查询和仪表板,跟踪每个分区的数据量、查询性能、膨胀情况等。

Q5: 如何实现监控数据的可视化?

A5: 监控数据的可视化需要考虑以下因素:

  1. 仪表板设计:根据监控目标和受众,设计清晰、直观的仪表板
  2. 图表类型选择:根据数据类型选择合适的图表类型,如折线图适合趋势数据,柱状图适合比较数据,饼图适合占比数据
  3. 颜色编码:使用颜色区分不同状态,如绿色表示正常,黄色表示警告,红色表示严重
  4. 交互性:支持时间范围选择、数据钻取、图表联动等交互功能
  5. 告警集成:在仪表板上显示告警状态和历史记录

Grafana 是实现监控数据可视化的理想工具,提供了丰富的图表类型和交互功能。