Skip to content

PostgreSQL 流复制监控

核心概念

1. 流复制监控的重要性

流复制监控是确保PostgreSQL主从复制架构稳定运行的关键环节:

  • 实时掌握复制状态:了解主从库之间的数据同步情况
  • 及时发现复制延迟:防止从库落后太多导致数据不一致
  • 提前预警复制故障:在问题扩大前采取措施
  • 优化复制性能:根据监控数据调整配置
  • 确保高可用性:为故障切换提供决策依据

2. 流复制监控的关键指标

  • 复制状态:从库是否处于正常复制状态
  • 复制延迟:主库与从库之间的WAL日志差距
  • WAL生成速率:主库生成WAL日志的速度
  • WAL应用速率:从库应用WAL日志的速度
  • 复制槽状态:复制槽是否正常,是否有积压
  • 系统资源使用:主从库的CPU、内存、磁盘、网络使用情况

3. 流复制监控的层次

PostgreSQL流复制监控可以分为三个层次:

  • 数据库内置视图:直接查询PostgreSQL提供的系统视图
  • 命令行工具:使用PostgreSQL自带的命令行工具
  • 第三方监控系统:使用专业的监控工具如Prometheus + Grafana

内置视图监控

1. pg_stat_replication(主库视图)

pg_stat_replication视图提供了主库上WAL发送进程的详细信息:

sql
-- 查看复制状态
SELECT 
    application_name,       -- 从库应用名称
    state,                 -- 复制状态(streaming, startup等)
    sync_state,            -- 同步状态(async, sync, potential等)
    sent_lsn,              -- 主库已发送的WAL位置
    write_lsn,             -- 从库已写入的WAL位置
    flush_lsn,             -- 从库已刷新到磁盘的WAL位置
    replay_lsn,            -- 从库已应用的WAL位置
    write_lag,             -- 写入延迟
    flush_lag,             -- 刷新延迟
    replay_lag,            -- 应用延迟
    write_time,            -- 写入时间
    flush_time,            -- 刷新时间
    replay_time            -- 应用时间
FROM pg_stat_replication;

2. pg_stat_wal_receiver(从库视图)

pg_stat_wal_receiver视图提供了从库上WAL接收进程的详细信息:

sql
-- 查看WAL接收状态
SELECT 
    pid,                   -- 进程ID
    status,                -- 接收状态
    receive_start_lsn,     -- 开始接收的WAL位置
    received_lsn,          -- 已接收的WAL位置
    last_msg_send_time,    -- 最后发送消息时间
    last_msg_receipt_time, -- 最后接收消息时间
    latest_end_lsn,        -- 最新结束WAL位置
    latest_end_time,       -- 最新结束时间
    slot_name,             -- 复制槽名称
    conninfo               -- 连接信息
FROM pg_stat_wal_receiver;

3. 复制延迟计算

sql
-- 方法1:使用内置函数计算复制延迟
SELECT 
    now() - pg_last_xact_replay_timestamp() AS replication_delay
FROM pg_stat_wal_receiver;

-- 方法2:通过LSN位置差计算延迟
SELECT 
    application_name,
    (sent_lsn - replay_lsn) / 1024 / 1024 AS replay_lag_mb
FROM pg_stat_replication;

4. pg_replication_slots(主库视图)

pg_replication_slots视图提供了复制槽的状态信息:

sql
-- 查看复制槽状态
SELECT 
    slot_name,             -- 复制槽名称
    plugin,                -- 插件名称
    slot_type,             -- 复制槽类型(physical, logical)
    database,              -- 数据库名称(逻辑复制)
    active,                -- 是否活跃
    xmin,                  -- 保留的最小事务ID
    catalog_xmin,          -- 保留的最小目录事务ID
    restart_lsn,           -- 重启LSN位置
    confirmed_flush_lsn    -- 确认刷新LSN位置
FROM pg_replication_slots;

命令行工具监控

1. 使用psql命令监控

bash
# 监控主库复制状态
psql -h 主库IP -U postgres -c "SELECT application_name, state, sync_state, sent_lsn, replay_lsn, (sent_lsn - replay_lsn) AS lag_mb FROM pg_stat_replication;"

# 监控从库复制状态
psql -h 从库IP -U postgres -c "SELECT pg_is_in_recovery(), now() - pg_last_xact_replay_timestamp() AS replication_delay;"

# 监控复制槽状态
psql -h 主库IP -U postgres -c "SELECT slot_name, active, restart_lsn, confirmed_flush_lsn FROM pg_replication_slots;"

2. 使用pg_controldata命令

bash
# 查看主库控制信息
pg_controldata 主库数据目录

# 查看从库控制信息
pg_controldata 从库数据目录

3. 使用pg_waldump命令

bash
# 查看WAL日志信息
pg_waldump -p 主库数据目录 -s 起始LSN -e 结束LSN

第三方工具监控

1. Prometheus + Grafana监控

1.1 安装pg_exporter

pg_exporter是一个用于导出PostgreSQL指标的Prometheus exporter:

bash
# 下载pg_exporter
wget https://github.com/prometheus-community/postgres_exporter/releases/download/v0.15.0/postgres_exporter-0.15.0.linux-amd64.tar.gz

# 解压
 tar -xzf postgres_exporter-0.15.0.linux-amd64.tar.gz
 cd postgres_exporter-0.15.0.linux-amd64

# 创建配置文件
cat > pg_exporter.yml << EOF
data_source_name: "postgresql://postgres:password@localhost:5432/postgres?sslmode=disable"
EOF

# 启动pg_exporter
./postgres_exporter --config.file=pg_exporter.yml --web.listen-address=:9187

1.2 配置Prometheus

在Prometheus配置文件中添加pg_exporter的抓取配置:

yaml
# prometheus.yml
global:
  scrape_interval: 15s

scrape_configs:
  - job_name: 'postgresql'
    static_configs:
      - targets: ['localhost:9187']

1.3 配置Grafana仪表板

  1. 登录Grafana
  2. 点击"Create" -> "Import"
  3. 输入仪表板ID:9628(PostgreSQL Database)或12633(PostgreSQL Replication)
  4. 选择Prometheus数据源
  5. 点击"Import"完成导入

2. 使用Zabbix监控

2.1 安装Zabbix Agent

bash
# 安装Zabbix Agent
sudo apt install zabbix-agent

# 配置Zabbix Agent
sudo nano /etc/zabbix/zabbix_agentd.conf

2.2 配置Zabbix监控项

在Zabbix Web界面中添加以下监控项:

  • 复制状态:使用pg_stat_replication视图
  • 复制延迟:使用now() - pg_last_xact_replay_timestamp()
  • WAL生成速率:监控WAL文件数量变化
  • WAL应用速率:监控从库WAL应用情况

3. 使用Nagios监控

3.1 安装Nagios插件

bash
# 安装Nagios插件
sudo apt install nagios-plugins-contrib

# 安装PostgreSQL Nagios插件
sudo apt install libmonitoring-plugin-perl libdbd-pg-perl
wget https://github.com/Checkmk/checkmk/blob/master/agents/check_mk_agent/plugins/postgresql -O /usr/lib/nagios/plugins/check_postgresql
chmod +x /usr/lib/nagios/plugins/check_postgresql

3.2 配置Nagios服务

在Nagios配置文件中添加以下服务:

txt
define service {
    host_name           postgresql-slave
    service_description PostgreSQL Replication Delay
    check_command       check_nrpe!check_postgres_replication_delay
    max_check_attempts  3
    check_interval      5
    retry_interval      1
    notification_interval 60
    notification_period 24x7
    contact_groups      admins
}

监控告警设置

1. 告警阈值设置

根据业务需求设置合理的告警阈值:

指标建议告警阈值严重程度
复制延迟> 30秒警告
复制延迟> 5分钟严重
复制状态非streaming严重
复制槽状态非active警告
WAL积压> 1GB警告
WAL积压> 10GB严重

2. 告警方式

  • 邮件告警:通过SMTP发送告警邮件
  • 短信告警:通过短信网关发送告警
  • 即时通讯告警:通过微信、Slack、钉钉等发送告警
  • 电话告警:对于严重故障,通过电话告警

3. 告警恢复通知

配置告警恢复通知,以便及时了解问题已解决:

yaml
# Prometheus Alertmanager配置
global:
  smtp_smarthost: 'smtp.example.com:587'
  smtp_from: 'alerts@example.com'
  smtp_auth_username: 'alerts@example.com'
  smtp_auth_password: 'password'

route:
  receiver: 'email-alerts'
  group_by: ['alertname', 'cluster', 'service']

receivers:
- name: 'email-alerts'
  email_configs:
  - to: 'admin@example.com'
    send_resolved: true  # 发送恢复通知

流复制性能监控

1. WAL生成和应用速率

sql
-- 监控WAL生成速率
SELECT 
    current_timestamp - interval '5 minutes' AS start_time,
    current_timestamp AS end_time,
    (pg_current_wal_lsn() - pg_wal_lsn_offset(pg_current_wal_lsn(), 300000000)) / 1024 / 1024 AS wal_generated_mb
FROM pg_stat_database;

-- 监控WAL应用速率(从库)
SELECT 
    current_timestamp - interval '5 minutes' AS start_time,
    current_timestamp AS end_time,
    (pg_last_wal_replay_lsn() - pg_wal_lsn_offset(pg_last_wal_replay_lsn(), 300000000)) / 1024 / 1024 AS wal_applied_mb
FROM pg_stat_database;

2. 系统资源监控

sql
-- 监控主从库的系统资源使用情况
-- 1. CPU使用率
SELECT 
    datname,
    numbackends,
    xact_commit,
    xact_rollback,
    blks_read,
    blks_hit,
    tup_returned,
    tup_fetched,
    tup_inserted,
    tup_updated,
    tup_deleted
FROM pg_stat_database;

-- 2. 磁盘使用情况
SELECT 
    datname,
    pg_size_pretty(pg_database_size(datname)) AS size
FROM pg_database;

常见问题处理

1. 复制延迟过高

问题现象:从库复制延迟超过告警阈值

解决方法

bash
# 1. 检查网络状态
ping 主库IP
netstat -s

# 2. 检查主库负载
top
psql -h 主库IP -U postgres -c "SELECT * FROM pg_stat_activity WHERE state = 'active';"

# 3. 检查从库负载
top
psql -h 从库IP -U postgres -c "SELECT * FROM pg_stat_activity WHERE state = 'active';"

# 4. 优化从库配置
# 增加从库的max_worker_processes和max_parallel_workers_per_gather参数
# 优化从库的WAL应用配置

2. 复制中断

问题现象:从库停止接收主库的WAL日志

解决方法

bash
# 1. 检查从库日志
cat /var/log/postgresql/postgresql-15-main.log

# 2. 检查主库pg_hba.conf配置
cat /etc/postgresql/15/main/pg_hba.conf

# 3. 检查主库max_wal_senders设置
psql -h 主库IP -U postgres -c "SHOW max_wal_senders;"

# 4. 重启从库复制
pg_ctl restart -D /var/lib/postgresql/15/main

3. 复制槽故障

问题现象:复制槽状态异常,有大量WAL日志积压

解决方法

sql
-- 1. 检查复制槽状态
SELECT * FROM pg_replication_slots;

-- 2. 清理无效的复制槽
SELECT pg_drop_replication_slot('slot_name');

-- 3. 重新创建复制槽
SELECT pg_create_physical_replication_slot('slot_name');

最佳实践

1. 监控配置最佳实践

  • 合理设置监控频率:根据业务重要性调整监控间隔
  • 设置多级告警阈值:区分警告和严重告警
  • 配置告警抑制规则:避免告警风暴
  • 定期测试告警:确保告警系统正常工作
  • 文档化监控配置:详细记录监控项和告警规则

2. 复制延迟管理最佳实践

  • 设置合理的wal_keep_size:防止从库落后太多导致WAL日志丢失
  • 使用复制槽:确保主库不会删除从库尚未接收的WAL日志
  • 优化从库性能:提高从库的WAL应用速度
  • 考虑使用级联复制:对于远距离从库,使用级联复制减少主库压力
  • 定期清理无效复制槽:避免复制槽积压过多WAL日志

3. 监控数据管理最佳实践

  • 设置合理的监控数据保留期:平衡存储成本和查询需求
  • 定期归档监控数据:对于长期分析,归档监控数据
  • 优化监控查询性能:避免监控查询影响数据库正常运行
  • 使用采样技术:对于高频指标,使用采样减少资源消耗

常见问题(FAQ)

Q1:如何监控多个从库的复制状态?

A1:可以使用以下方法:

  • 在主库上查询pg_stat_replication视图,该视图会显示所有连接的从库
  • 使用Prometheus + Grafana监控,在一个仪表板上显示所有从库的状态
  • 使用Zabbix或Nagios等监控系统,为每个从库配置独立的监控项

Q2:如何区分正常复制延迟和异常复制延迟?

A2:可以通过以下方式判断:

  • 根据业务需求设置合理的告警阈值
  • 分析WAL生成速率和应用速率的差异
  • 监控从库的系统资源使用情况
  • 对比历史复制延迟数据

Q3:pg_stat_replication视图中没有数据怎么办?

A3:可能的原因包括:

  • 从库没有连接到主库
  • 主库的max_wal_senders参数设置过小
  • 主库的pg_hba.conf没有允许从库连接
  • 复制用户的权限不足

Q4:如何监控逻辑复制?

A4:可以使用以下视图监控逻辑复制:

sql
-- 监控发布者状态
SELECT * FROM pg_stat_publication;

-- 监控订阅者状态
SELECT * FROM pg_stat_subscription;

-- 监控复制槽状态
SELECT * FROM pg_replication_slots WHERE slot_type = 'logical';

Q5:如何监控复制槽的WAL积压情况?

A5:可以使用以下查询:

sql
SELECT 
    slot_name,
    pg_wal_lsn_diff(pg_current_wal_lsn(), restart_lsn) / 1024 / 1024 AS wal_backlog_mb
FROM pg_replication_slots;

Q6:如何使用脚本自动化监控复制状态?

A6:可以编写Shell脚本结合cron定期监控:

bash
#!/bin/bash

# 复制延迟监控脚本
REPLICATION_DELAY=$(psql -h 从库IP -U postgres -t -c "SELECT EXTRACT(EPOCH FROM (now() - pg_last_xact_replay_timestamp()));")

# 设置告警阈值(秒)
THRESHOLD=30

if (( $(echo "$REPLICATION_DELAY > $THRESHOLD" | bc -l) )); then
    # 发送告警
    echo "Replication delay exceeds threshold: $REPLICATION_DELAY seconds" | mail -s "PostgreSQL Replication Alert" admin@example.com
fi

Q7:如何监控WAL归档状态?

A7:可以使用以下方法:

sql
-- 检查WAL归档状态
SELECT 
    archiver_pid,
    archived_count,
    failed_count,
    last_archived_wal,
    last_archived_time,
    last_failed_wal,
    last_failed_time
FROM pg_stat_archiver;

Q8:如何监控复制的网络流量?

A8:可以使用以下方法:

  • 使用iftopnethogs命令监控网络流量
  • 在主库上监控pg_stat_replication视图中的WAL传输情况
  • 使用Prometheus监控pg_exporter导出的网络相关指标
  • 配置网络设备的流量监控

流复制监控的未来发展

随着PostgreSQL的发展,流复制监控也在不断改进:

  • 更丰富的指标:PostgreSQL 15+提供了更多复制相关的指标
  • 更强大的监控工具:pg_exporter和Grafana仪表板不断更新
  • 更智能的告警:基于机器学习的异常检测
  • 更全面的可视化:实时数据流向图和拓扑图
  • 更便捷的配置:自动化监控配置和管理

通过合理配置和使用流复制监控,可以确保PostgreSQL主从复制架构的稳定运行,提高系统的可用性和可靠性。