Skip to content

PostgreSQL Nagios监控

Nagios监控架构

Nagios核心组件

  1. Nagios Core

    • 监控系统的核心引擎
    • 负责调度监控检查
    • 处理告警逻辑
    • 生成监控报告
  2. Nagios Plugins

    • 用于执行具体监控检查的脚本
    • 支持多种监控协议和服务
    • 可以自定义开发
  3. NRPE (Nagios Remote Plugin Executor)

    • 用于在远程主机上执行监控插件
    • 减少Nagios服务器的负载
    • 提高监控安全性
  4. NSCA (Nagios Service Check Acceptor)

    • 用于接收远程主机主动发送的监控结果
    • 适合监控防火墙后的主机
    • 支持加密传输
  5. Nagios Web界面

    • 提供图形化监控视图
    • 支持告警确认和注释
    • 生成历史报告和趋势图

PostgreSQL监控架构

  1. 监控数据流

    • Nagios服务器定期执行监控检查
    • 通过NRPE或直接连接到PostgreSQL服务器
    • 执行监控插件收集PostgreSQL状态信息
    • 将结果返回给Nagios服务器
    • 根据预定义规则触发告警
  2. 监控层次

    • 系统级监控:CPU、内存、磁盘、网络
    • PostgreSQL服务监控:服务状态、连接数
    • 数据库级监控:数据库大小、事务数
    • 表级监控:表大小、索引使用情况
    • 查询级监控:慢查询、锁等待

Nagios插件安装与配置

安装Nagios插件

  1. 安装Nagios核心

    bash
    # CentOS/RHEL系统
    yum install -y nagios nagios-plugins-all
    
    # Ubuntu/Debian系统
    apt update
    apt install -y nagios3 nagios-plugins
  2. 安装PostgreSQL监控插件

    bash
    # 安装check_postgres插件
    wget https://github.com/bucardo/check_postgres/archive/refs/tags/v2.25.0.tar.gz
    tar -zxvf v2.25.0.tar.gz
    cd check_postgres-2.25.0
    perl Makefile.PL
    make && make install
    
    # 验证安装
    /usr/local/bin/check_postgres.pl --help
  3. 安装NRPE (可选)

    bash
    # CentOS/RHEL系统
    yum install -y nrpe nagios-plugins-nrpe
    
    # Ubuntu/Debian系统
    apt install -y nagios-nrpe-server

配置监控插件

  1. 创建监控用户

    sql
    -- 在PostgreSQL中创建监控用户
    CREATE USER nagios_monitor WITH PASSWORD 'nagios_password' NOSUPERUSER NOCREATEDB NOCREATEROLE;
    GRANT SELECT ON ALL TABLES IN SCHEMA pg_catalog TO nagios_monitor;
    GRANT SELECT ON ALL TABLES IN SCHEMA information_schema TO nagios_monitor;
  2. 配置pg_hba.conf

    txt
    # 允许Nagios服务器连接
    host    all             nagios_monitor      192.168.1.100/32            md5
  3. 配置check_postgres插件

    bash
    # 创建插件配置文件
    cat > /etc/nagios/check_postgres.conf << EOF
    [postgres]
    dbname=postgres
    port=5432
    user=nagios_monitor
    password=nagios_password
    EOF
    
    # 设置权限
    chmod 600 /etc/nagios/check_postgres.conf
    chown nagios:nagios /etc/nagios/check_postgres.conf
  4. 测试插件运行

    bash
    # 测试PostgreSQL连接
    /usr/local/bin/check_postgres.pl --action=connection --dbname=postgres --port=5432 --username=nagios_monitor --password=nagios_password
    
    # 测试数据库大小
    /usr/local/bin/check_postgres.pl --action=database_size --dbname=postgres --port=5432 --username=nagios_monitor --password=nagios_password

Nagios监控项配置

配置命令定义

  1. 在commands.cfg中添加命令

    txt
    # /etc/nagios/objects/commands.cfg
    
    # check_postgres连接检查
    define command {
        command_name    check_postgres_connection
        command_line    /usr/local/bin/check_postgres.pl --action=connection --dbname='$ARG1$' --port='$ARG2$' --username='$ARG3$' --password='$ARG4$' -w '$ARG5$' -c '$ARG6$'
    }
    
    # check_postgres数据库大小检查
    define command {
        command_name    check_postgres_db_size
        command_line    /usr/local/bin/check_postgres.pl --action=database_size --dbname='$ARG1$' --port='$ARG2$' --username='$ARG3$' --password='$ARG4$' -w '$ARG5$' -c '$ARG6$'
    }
    
    # check_postgres连接数检查
    define command {
        command_name    check_postgres_connections
        command_line    /usr/local/bin/check_postgres.pl --action=connection_count --dbname='$ARG1$' --port='$ARG2$' --username='$ARG3$' --password='$ARG4$' -w '$ARG5$' -c '$ARG6$'
    }
    
    # check_postgres慢查询检查
    define command {
        command_name    check_postgres_slow_queries
        command_line    /usr/local/bin/check_postgres.pl --action=slow_queries --dbname='$ARG1$' --port='$ARG2$' --username='$ARG3$' --password='$ARG4$' -w '$ARG5$' -c '$ARG6$'
    }
    
    # check_postgres复制延迟检查
    define command {
        command_name    check_postgres_replication_delay
        command_line    /usr/local/bin/check_postgres.pl --action=replication_delay --dbname='$ARG1$' --port='$ARG2$' --username='$ARG3$' --password='$ARG4$' -w '$ARG5$' -c '$ARG6$'
    }

配置主机和服务

  1. 定义PostgreSQL主机

    txt
    # /etc/nagios/objects/postgresql.cfg
    
    define host {
        use                     linux-server
        host_name               postgres-server-01
        alias                   PostgreSQL主服务器
        address                 192.168.1.20
        max_check_attempts      3
        check_interval          5
        retry_interval          1
        check_command           check-host-alive
        contact_groups          admins
    }
  2. 定义PostgreSQL服务

    txt
    # PostgreSQL服务状态检查
    define service {
        use                     generic-service
        host_name               postgres-server-01
        service_description     PostgreSQL Service Status
        check_command           check_tcp!5432
        max_check_attempts      3
        check_interval          5
        retry_interval          1
        contact_groups          admins
    }
    
    # PostgreSQL连接检查
    define service {
        use                     generic-service
        host_name               postgres-server-01
        service_description     PostgreSQL Connections
        check_command           check_postgres_connection!postgres!5432!nagios_monitor!nagios_password!50!100
        max_check_attempts      3
        check_interval          5
        retry_interval          1
        contact_groups          admins
    }
    
    # PostgreSQL数据库大小检查
    define service {
        use                     generic-service
        host_name               postgres-server-01
        service_description     PostgreSQL Database Size
        check_command           check_postgres_db_size!postgres!5432!nagios_monitor!nagios_password!5GB!10GB
        max_check_attempts      3
        check_interval          30
        retry_interval          5
        contact_groups          admins
    }
    
    # PostgreSQL慢查询检查
    define service {
        use                     generic-service
        host_name               postgres-server-01
        service_description     PostgreSQL Slow Queries
        check_command           check_postgres_slow_queries!postgres!5432!nagios_monitor!nagios_password!10!20
        max_check_attempts      3
        check_interval          10
        retry_interval          2
        contact_groups          admins
    }
    
    # PostgreSQL复制延迟检查
    define service {
        use                     generic-service
        host_name               postgres-server-01
        service_description     PostgreSQL Replication Delay
        check_command           check_postgres_replication_delay!postgres!5432!nagios_monitor!nagios_password!30!60
        max_check_attempts      3
        check_interval          5
        retry_interval          1
        contact_groups          admins
    }

配置NRPE (可选)

  1. 配置NRPE服务器

    txt
    # /etc/nagios/nrpe.cfg
    
    # 允许Nagios服务器连接
    allowed_hosts=127.0.0.1,192.168.1.100
    
    # 定义NRPE命令
    command[check_postgres_connections]=/usr/local/bin/check_postgres.pl --action=connection_count --dbname=postgres --port=5432 --username=nagios_monitor --password=nagios_password -w 50 -c 100
    command[check_postgres_db_size]=/usr/local/bin/check_postgres.pl --action=database_size --dbname=postgres --port=5432 --username=nagios_monitor --password=nagios_password -w 5GB -c 10GB
    command[check_postgres_slow_queries]=/usr/local/bin/check_postgres.pl --action=slow_queries --dbname=postgres --port=5432 --username=nagios_monitor --password=nagios_password -w 10 -c 20
  2. 在Nagios中配置NRPE命令

    txt
    # /etc/nagios/objects/commands.cfg
    
    define command {
        command_name    check_nrpe
        command_line    /usr/lib64/nagios/plugins/check_nrpe -H '$HOSTADDRESS$' -c '$ARG1$'
    }
    
    # 使用NRPE检查PostgreSQL连接
    define service {
        use                     generic-service
        host_name               postgres-server-01
        service_description     PostgreSQL Connections (NRPE)
        check_command           check_nrpe!check_postgres_connections
        max_check_attempts      3
        check_interval          5
        retry_interval          1
        contact_groups          admins
    }

关键监控项与阈值设置

以下是 PostgreSQL Nagios 监控的关键监控项及其配置,使用 mermaid 流程图展示:

告警配置与通知

告警级别配置

  1. 配置告警联系人

    txt
    # /etc/nagios/objects/contacts.cfg
    define contact {
        contact_name                    nagiosadmin
        use                             generic-contact
        alias                           Nagios Admin
        email                           nagiosadmin@example.com
        service_notification_period     24x7
        host_notification_period        24x7
        service_notification_options    w,u,c,r,f,s
        host_notification_options       d,u,r,f,s
        service_notification_commands   notify-service-by-email
        host_notification_commands      notify-host-by-email
    }
    
    define contactgroup {
        contactgroup_name       admins
        alias                   Nagios Administrators
        members                 nagiosadmin
    }
  2. 配置告警命令

    txt
    # /etc/nagios/objects/commands.cfg
    
    define command {
        command_name    notify-host-by-email
        command_line    /usr/bin/printf "%b" "***** Nagios *****\n\nNotification Type: $NOTIFICATIONTYPE$\nHost: $HOSTNAME$\nState: $HOSTSTATE$\nAddress: $HOSTADDRESS$\nInfo: $HOSTOUTPUT$\n\nDate/Time: $LONGDATETIME$\n" | /usr/bin/mail -s "** $NOTIFICATIONTYPE$ Host Alert: $HOSTNAME$ is $HOSTSTATE$ **" $CONTACTEMAIL$
    }
    
    define command {
        command_name    notify-service-by-email
        command_line    /usr/bin/printf "%b" "***** Nagios *****\n\nNotification Type: $NOTIFICATIONTYPE$\n\nService: $SERVICEDESC$\nHost: $HOSTALIAS$\nAddress: $HOSTADDRESS$\nState: $SERVICESTATE$\n\nDate/Time: $LONGDATETIME$\n\nAdditional Info:\n\n$SERVICEOUTPUT$\n" | /usr/bin/mail -s "** $NOTIFICATIONTYPE$ Service Alert: $HOSTALIAS$/$SERVICEDESC$ is $SERVICESTATE$ **" $CONTACTEMAIL$
    }
  3. 配置告警升级

    txt
    # /etc/nagios/objects/timeperiods.cfg
    define timeperiod {
        timeperiod_name            24x7
        alias                      24 Hours A Day, 7 Days A Week
        sunday                     00:00-24:00
        monday                     00:00-24:00
        tuesday                    00:00-24:00
        wednesday                  00:00-24:00
        thursday                   00:00-24:00
        friday                     00:00-24:00
        saturday                   00:00-24:00
    }
    
    # 告警升级配置
    define serviceescalation {
        host_name                   postgres-server-01
        service_description         PostgreSQL Replication Delay
        first_notification          1
        last_notification           3
        notification_interval       5
        contact_groups              admins
        escalation_period           24x7
    }

告警通知方式

  1. 邮件通知

    • 配置SMTP服务器
    • 测试邮件发送
    • 调整邮件模板
  2. 短信通知

    • 安装短信网关
    • 配置Nagios短信命令
    • 测试短信发送
  3. 即时通讯工具

    • Slack通知:使用slack_nagios.pl插件
    • Telegram通知:使用telegram-nagios插件
    • 微信通知:使用企业微信或第三方插件
  4. 自动语音呼叫

    • 安装语音网关
    • 配置Nagios语音命令
    • 设置紧急告警语音通知

Nagios监控高级配置

自定义监控插件开发

  1. Perl插件开发示例

    perl
    #!/usr/bin/perl
    # 自定义PostgreSQL监控插件
    
    use strict;
    use warnings;
    use DBI;
    
    # 插件参数
    my $dbname = shift || 'postgres';
    my $port = shift || 5432;
    my $username = shift || 'nagios_monitor';
    my $password = shift || 'nagios_password';
    my $warning = shift || 10;
    my $critical = shift || 20;
    
    # 连接到PostgreSQL
    my $dsn = "DBI:Pg:dbname=$dbname;host=localhost;port=$port";
    my $dbh = DBI->connect($dsn, $username, $password) or die "Could not connect: " . DBI->errstr;
    
    # 执行查询
    my $query = "SELECT count(*) FROM pg_stat_activity WHERE state = 'active'";
    my $sth = $dbh->prepare($query);
    $sth->execute();
    my ($active_connections) = $sth->fetchrow_array();
    
    # 关闭连接
    $sth->finish();
    $dbh->disconnect();
    
    # 检查结果
    if ($active_connections >= $critical) {
        print "CRITICAL - Active connections: $active_connections | connections=$active_connections;$warning;$critical\n";
        exit 2;
    } elsif ($active_connections >= $warning) {
        print "WARNING - Active connections: $active_connections | connections=$active_connections;$warning;$critical\n";
        exit 1;
    } else {
        print "OK - Active connections: $active_connections | connections=$active_connections;$warning;$critical\n";
        exit 0;
    }
  2. Python插件开发示例

    python
    #!/usr/bin/env python3
    # 自定义PostgreSQL监控插件
    
    import sys
    import psycopg2
    from psycopg2 import OperationalError
    
    def main():
        # 插件参数
        dbname = sys.argv[1] if len(sys.argv) > 1 else 'postgres'
        port = sys.argv[2] if len(sys.argv) > 2 else '5432'
        username = sys.argv[3] if len(sys.argv) > 3 else 'nagios_monitor'
        password = sys.argv[4] if len(sys.argv) > 4 else 'nagios_password'
        warning = int(sys.argv[5]) if len(sys.argv) > 5 else 10
        critical = int(sys.argv[6]) if len(sys.argv) > 6 else 20
    
        try:
            # 连接到PostgreSQL
            conn = psycopg2.connect(
                dbname=dbname,
                user=username,
                password=password,
                host='localhost',
                port=port
            )
            cursor = conn.cursor()
    
            # 执行查询
            cursor.execute("SELECT count(*) FROM pg_stat_activity WHERE state = 'active'")
            active_connections = cursor.fetchone()[0]
    
            # 关闭连接
            cursor.close()
            conn.close()
    
            # 检查结果
            if active_connections >= critical:
                print(f"CRITICAL - Active connections: {active_connections} | connections={active_connections};{warning};{critical}")
                sys.exit(2)
            elif active_connections >= warning:
                print(f"WARNING - Active connections: {active_connections} | connections={active_connections};{warning};{critical}")
                sys.exit(1)
            else:
                print(f"OK - Active connections: {active_connections} | connections={active_connections};{warning};{critical}")
                sys.exit(0)
        except OperationalError as e:
            print(f"CRITICAL - Could not connect to PostgreSQL: {e}")
            sys.exit(2)
    
    if __name__ == "__main__":
        main()

监控数据可视化

  1. Nagios Graph插件

    • 安装pnp4nagios
    • 配置Nagios使用pnp4nagios
    • 生成性能趋势图
  2. Grafana集成

    • 安装Grafana
    • 配置PostgreSQL数据源
    • 导入PostgreSQL监控仪表盘
    • 设置告警规则
  3. InfluxDB集成

    • 安装InfluxDB
    • 配置Nagios将数据发送到InfluxDB
    • 使用Grafana可视化数据

高可用性配置

  1. Nagios服务器高可用

    • 配置Nagios主备服务器
    • 使用DRBD同步数据
    • 配置Pacemaker实现自动故障转移
  2. 监控代理高可用

    • 部署多个NRPE服务器
    • 配置负载均衡
    • 实现故障自动切换

常见问题与故障处理

监控插件执行失败

  1. 问题现象

    • Nagios显示"Plugin timed out"
    • 插件返回"CRITICAL - Could not connect to PostgreSQL"
    • 插件权限错误
  2. 排查步骤

    • 检查PostgreSQL服务是否运行
    • 验证监控用户权限
    • 测试插件命令直接执行
    • 检查防火墙设置
  3. 解决方案

    • 重启PostgreSQL服务
    • 重新配置监控用户权限
    • 修复插件权限问题
    • 调整防火墙规则

告警风暴

  1. 问题现象

    • 短时间内收到大量告警
    • 重复告警频繁出现
    • 告警通知渠道过载
  2. 排查步骤

    • 检查PostgreSQL服务器状态
    • 分析告警类型和触发原因
    • 检查监控阈值设置
  3. 解决方案

    • 调整告警阈值
    • 配置告警抑制规则
    • 设置告警升级间隔
    • 优化监控检查间隔

监控数据不准确

  1. 问题现象

    • 监控数据与实际情况不符
    • 数据波动过大
    • 数据缺失
  2. 排查步骤

    • 验证监控插件逻辑
    • 检查PostgreSQL统计信息
    • 分析监控数据采集频率
  3. 解决方案

    • 修复监控插件bug
    • 手动刷新PostgreSQL统计信息
    • 调整监控检查间隔
    • 优化数据存储和处理

NRPE连接失败

  1. 问题现象

    • Nagios显示"CHECK_NRPE: Error - Could not complete SSL handshake"
    • NRPE服务无法启动
    • 权限错误
  2. 排查步骤

    • 检查NRPE服务状态
    • 验证NRPE配置文件
    • 测试NRPE连接
    • 检查SSL配置
  3. 解决方案

    • 重启NRPE服务
    • 修复NRPE配置错误
    • 调整SSL设置
    • 检查防火墙规则

Nagios监控最佳实践

监控策略设计

  1. 分层监控

    • 系统层监控:CPU、内存、磁盘
    • 服务层监控:PostgreSQL服务状态
    • 应用层监控:数据库性能指标
    • 业务层监控:关键业务指标
  2. 监控项优先级

    • 核心服务监控:高优先级,短检查间隔
    • 性能监控:中优先级,中等检查间隔
    • 资源监控:低优先级,长检查间隔
  3. 告警策略

    • 明确告警责任人
    • 分级告警:警告、严重、紧急
    • 告警升级机制
    • 告警确认流程

监控维护

  1. 定期检查

    • 每周检查监控插件状态
    • 每月调整监控阈值
    • 每季度更新监控插件
    • 每年进行监控系统演练
  2. 文档管理

    • 维护监控项文档
    • 更新告警规则文档
    • 记录故障处理过程
    • 编写监控系统手册
  3. 性能优化

    • 优化监控检查间隔
    • 减少不必要的监控项
    • 优化监控插件性能
    • 调整Nagios配置参数

故障响应流程

  1. 告警确认

    • 收到告警后立即确认
    • 初步判断告警级别
    • 通知相关责任人
  2. 故障排查

    • 检查PostgreSQL服务状态
    • 分析监控数据和日志
    • 定位故障原因
    • 制定修复方案
  3. 故障修复

    • 执行修复操作
    • 验证修复效果
    • 更新监控状态
    • 记录修复过程
  4. 事后分析

    • 分析故障原因
    • 评估监控系统表现
    • 提出改进措施
    • 更新监控策略

不同版本PostgreSQL的监控差异

PostgreSQL 9.x

  1. 监控项限制

    • 部分性能指标不可用
    • 复制监控功能有限
    • 慢查询日志格式不同
  2. 插件兼容性

    • 需要使用旧版本的check_postgres插件
    • 某些高级监控项不支持
    • 需要调整监控脚本

PostgreSQL 10.x及以上

  1. 新监控功能

    • 增强的复制监控
    • 更详细的性能统计
    • 逻辑复制监控
    • 分区表监控
  2. 插件优化

    • 使用最新版本的check_postgres插件
    • 支持更多监控项
    • 性能更优

监控配置调整

  1. 根据版本调整监控项

    • 针对不同版本启用或禁用监控项
    • 调整监控阈值
    • 更新监控插件版本
  2. 兼容性处理

    • 编写兼容多版本的监控脚本
    • 使用条件判断处理版本差异
    • 测试不同版本的监控效果

Nagios监控案例分析

案例1:PostgreSQL连接数过高告警

  1. 问题描述

    • Nagios发送"PostgreSQL Connections CRITICAL"告警
    • 应用程序无法连接到PostgreSQL
    • 服务器CPU使用率过高
  2. 处理过程

    • 登录PostgreSQL服务器
    • 执行pg_stat_activity查看连接状态
    • 发现大量空闲连接
    • 调整max_connections参数
    • 配置连接超时
  3. 解决方案

    • 增加max_connections到200
    • 设置idle_in_transaction_session_timeout = 300000
    • 配置连接池
    • 优化应用程序连接管理

案例2:复制延迟告警

  1. 问题描述

    • Nagios发送"PostgreSQL Replication Delay CRITICAL"告警
    • 从库复制延迟超过60秒
    • 主库WAL日志堆积
  2. 处理过程

    • 检查主从库网络连接
    • 查看主库WAL生成速率
    • 检查从库WAL应用速率
    • 发现从库I/O瓶颈
  3. 解决方案

    • 优化从库存储性能
    • 调整主库WAL参数
    • 启用并行复制
    • 增加从库资源

案例3:慢查询告警

  1. 问题描述

    • Nagios发送"PostgreSQL Slow Queries CRITICAL"告警
    • 慢查询数超过20个
    • 数据库响应变慢
  2. 处理过程

    • 分析慢查询日志
    • 使用EXPLAIN ANALYZE分析查询计划
    • 发现缺少索引
    • 优化查询语句
  3. 解决方案

    • 为频繁查询的列添加索引
    • 重写复杂查询
    • 调整work_mem参数
    • 优化数据库统计信息

常见问题(FAQ)

Q1: 如何选择合适的监控插件?

A1: 选择监控插件时需要考虑:

  • 插件的功能完整性
  • 与PostgreSQL版本的兼容性
  • 插件的性能开销
  • 社区支持和更新频率
  • 自定义扩展能力

Q2: 如何设置合理的监控阈值?

A2: 设置监控阈值时需要考虑:

  • 系统的正常运行范围
  • 业务需求和SLA要求
  • 历史数据趋势
  • 资源容量限制
  • 告警频率和处理能力

Q3: 如何减少监控对PostgreSQL性能的影响?

A3: 可以通过以下方法减少监控影响:

  • 调整监控检查间隔
  • 减少不必要的监控项
  • 使用只读监控用户
  • 优化监控插件性能
  • 部署专用监控服务器

Q4: 如何实现PostgreSQL的自动故障恢复?

A4: 实现自动故障恢复可以考虑:

  • 使用Patroni或repmgr实现PostgreSQL自动故障转移
  • 配置Nagios与自动化工具集成
  • 编写自定义恢复脚本
  • 建立故障恢复流程和文档

Q5: 如何监控PostgreSQL集群?

A5: 监控PostgreSQL集群需要:

  • 监控每个节点的状态
  • 监控集群复制状态
  • 监控集群性能指标
  • 监控集群一致性
  • 配置集群级告警规则

Q6: 如何集成Nagios与其他监控系统?

A6: 集成Nagios与其他监控系统可以:

  • 使用Nagios的API导出数据
  • 配置Nagios将数据发送到中央监控系统
  • 使用第三方集成工具
  • 开发自定义集成插件

Q7: 如何优化Nagios监控性能?

A7: 优化Nagios监控性能可以:

  • 调整Nagios配置参数
  • 优化监控检查间隔
  • 使用NRPE减少网络开销
  • 优化监控插件
  • 升级Nagios服务器硬件

Q8: 如何实现PostgreSQL的预测性监控?

A8: 实现预测性监控可以:

  • 收集长期监控数据
  • 使用机器学习算法分析趋势
  • 建立预测模型
  • 设置预测性告警阈值
  • 集成预测分析工具