A-speed

每个人都是🏆
  新随笔  :: 管理

PostgreSQL 主从库监控接入详细过程

Posted on 2026-10-10 11:35  a-speed  阅读(6)  评论(0)    收藏  举报

PostgreSQL 主从库监控接入详细过程

适用环境:node2 (192.168.56.132)・RHEL 8.6・PostgreSQL 18・Prometheus 3.11.2・Grafana 6.0.1
整理日期:2026-10-10
文档性质:把 PostgreSQL 主从库(5433/5434)纳入 Prometheus+Grafana 监控的完整操作过程,命令可复现


1. 背景与目标

已有一台 PG 实例(5432,/var/lib/pgsql/18/data)在用 9187 exporter 监控。本次要把新增的主从库也纳入监控:

库 数据目录 端口 角色(实测)
主库 /data/postgres/master 5433 standby(恢复模式)
从库 /data/postgres/slave 5434 standby,从 5433 拉取(streaming)

连接账号:itdba / 密码 Lihj2026(用户提供)。


2. 前置探查(动手前确认)

2.1 端口监听与进程

ss -tlnp | grep -E ':5432|:5433|:5434|:9187'
# 0.0.0.0:5432  postgres   ← 已有实例
# 0.0.0.0:5433  postgres   ← 主库
# 0.0.0.0:5434  postgres   ← 从库
# *:9187        postgres_export  ← 已有 exporter

ps -ef | grep -E 'postgres.*-D'
# postgres 8967 ... -D /data/postgres/master    (5433)
# postgres 8982 ... -D /data/postgres/slave     (5434)

2.2 主从角色核实(关键!)

# 角色判断
PGPASSWORD=Lihj2026 psql -h127.0.0.1 -p5433 -Uitdba -dpostgres -tA -c 'SELECT pg_is_in_recovery()'
# t   ← 恢复模式

PGPASSWORD=Lihj2026 psql -h127.0.0.1 -p5434 -Uitdba -dpostgres -tA -c 'SELECT pg_is_in_recovery()'
# t   ← 恢复模式

# 复制状态(在从库上看谁在拉)
PGPASSWORD=Lihj2026 psql -h127.0.0.1 -p5434 -Uitdba -dpostgres -c 'SELECT client_addr,state,sync_state FROM pg_stat_replication;'
# ::1 | streaming | async

# 数据目录确认
ls /data/postgres/master/ | grep standby.signal   # 存在 → 5433 也是 standby
ls /data/postgres/slave/  | grep standby.signal   # 存在 → 5434 是 standby

⚠️ 重要发现:5433 和 5434 都处于 standby 只读模式(pg_is_in_recovery()=t,CREATE TABLE 报 read-only)。从库 5434 从 5433 拉取(streaming/async),但 5433 自身也带 standby.signal。这是级联/双 standby 拓扑,当前无可写主库。

不影响监控:postgres_exporter 采集的是状态指标(连接数、缓冲、WAL、数据库统计等),对只读 standby 完全适用。

2.3 采集账号权限

PGPASSWORD=Lihj2026 psql -h127.0.0.1 -p5433 -Uitdba -dpostgres -tA -c 'SELECT count(*) FROM pg_stat_database;'
# 4   ← itdba 可读 pg_stat 视图,权限充足

3. 方案:独立双 exporter(用户选定)

每个库一个 postgres_exporter 实例,各监听独立端口,各连各的库,Prometheus 加两个 target:

PG 主库(5433) ──► postgres-exporter-master (9188) ──► Prometheus job pg-master
PG 从库(5434) ──► postgres-exporter-slave  (9189) ──► Prometheus job pg-slave

4. 创建并启动两个 exporter 服务

4.1 主库 exporter 服务 /etc/systemd/system/postgres-exporter-master.service

[Unit]
Description=PostgreSQL Exporter (Master 5433)
After=network.target
[Service]
Type=simple
User=postgres
Environment="DATA_SOURCE_NAME=postgresql://itdba:Lihj2026@127.0.0.1:5433/postgres?sslmode=disable"
ExecStart=/usr/local/bin/postgres_exporter --no-collector.stat_bgwriter --web.listen-address=:9188 --log.level=error
Restart=always
[Install]
WantedBy=multi-user.target

4.2 从库 exporter 服务 /etc/systemd/system/postgres-exporter-slave.service

[Unit]
Description=PostgreSQL Exporter (Slave 5434)
After=network.target
[Service]
Type=simple
User=postgres
Environment="DATA_SOURCE_NAME=postgresql://itdba:Lihj2026@127.0.0.1:5434/postgres?sslmode=disable"
ExecStart=/usr/local/bin/postgres_exporter --no-collector.stat_bgwriter --web.listen-address=:9189 --log.level=error
Restart=always
[Install]
WantedBy=multi-user.target

说明:--no-collector.stat_bgwriter 沿用既有实例的关闭项(避免不必要的采集);DSN 里 127.0.0.1 走本地回环(安全),sslmode=disable 因本地无 SSL 配置。

4.3 启用并启动

systemctl daemon-reload
systemctl enable postgres-exporter-master postgres-exporter-slave
systemctl start  postgres-exporter-master postgres-exporter-slave
systemctl is-active postgres-exporter-master postgres-exporter-slave
# active
# active
ss -tlnp | grep -E ':9188|:9189'
# *:9188  postgres_export
# *:9189  postgres_export

4.4 验证采集

curl -s http://127.0.0.1:9188/metrics | grep -E '^pg_up|^pg_settings_max_connections'
# pg_up 1
# pg_settings_max_connections{server="127.0.0.1:5433"} 100

curl -s http://127.0.0.1:9189/metrics | grep -E '^pg_up|^pg_settings_max_connections'
# pg_up 1
# pg_settings_max_connections{server="127.0.0.1:5434"} 100

✅ 两个 exporter 均 pg_up=1,server 标签正确区分 5433/5434。


5. 添加到 Prometheus

5.1 备份并追加 job

cp /etc/prometheus/prometheus.yml /etc/prometheus/prometheus.yml.bak2

在 scrape_configs: 末尾(mysql job 之后)追加:

  - job_name: 'pg-master'
    scrape_interval: 5s
    static_configs:
      - targets: ['192.168.56.132:9188']
        labels:
          instance: 'prod-pg-master-5433'
          env: 'production'

  - job_name: 'pg-slave'
    scrape_interval: 5s
    static_configs:
      - targets: ['192.168.56.132:9189']
        labels:
          instance: 'prod-pg-slave-5434'
          env: 'production'

5.2 重载并验证 target

systemctl reload prometheus

curl -s http://127.0.0.1:9090/api/v1/targets | python3 -m json.tool
# mysql prod-mysql-01        -> up
# pg-master prod-pg-master-5433 -> up
# pg-slave prod-pg-slave-5434  -> up
# postgresql prod-postgres-01  -> up
# prometheus localhost:9090    -> up

注:新 job 首次显示 unknown 属正常,等 1~2 个抓取周期后变 up。

5.3 验证指标入库

curl -s 'http://127.0.0.1:9090/api/v1/query?query=pg_up'
# postgresql prod-postgres-01    = 1
# pg-master   prod-pg-master-5433 = 1
# pg-slave    prod-pg-slave-5434  = 1

6. 端到端验证(Grafana 层)

# 通过 Grafana 数据源代理查询
curl -s -u admin:Lihj2026 'http://127.0.0.1:3000/api/datasources/proxy/1/api/v1/query?query=pg_up'
# postgresql = 1
# pg-master  = 1
# pg-slave   = 1

✅ Grafana 数据源代理能取到 PG 主从指标,链路完整(exporter → Prometheus → Grafana 全通)。


7. 结果汇总

资源 监听端口 Prometheus job instance 状态
PG 主库 5433 9188 pg-master prod-pg-master-5433 ✅ up, pg_up=1
PG 从库 5434 9189 pg-slave prod-pg-slave-5434 ✅ up, pg_up=1

新增服务:postgres-exporter-master、postgres-exporter-slave(均已 enable 开机自启)。
配置文件:/etc/systemd/system/postgres-exporter-{master,slave}.service;prometheus.yml 备份 .bak2。


8. 常见排查

现象 排查
exporter pg_up=0 DSN 账号密码错误 / PG 未运行 / pg_hba.conf 未放行 127.0.0.1
端口被占 9188/9189 被占用,改 --web.listen-address
target 一直 unknown 等抓取周期;或 exporter 未起、端口不通
Grafana 无主从数据 确认数据源代理查询通、job 名/instance 是否正确

9. 待确认 / 后续

  • 当前两个库都是 standby(无可写主库)——如后续把 5433 提升为主(rm standby.signal + promote),exporter 无需改动,指标自动反映。
  • 如需在 Grafana 为 PG 主从建独立面板,可参照既有 PostgreSQL Database 面板模板(含 instance 变量区分主/从)。
  • 复制的核心指标(pg_stat_replication 状态、pg_wal_receiver 延迟)可在面板中用 pg_stat_replication_* 系列查看。

本文档记录 2026-10-10 在 node2 上把 PostgreSQL 主从库(5433/5434) 接入 Prometheus+Grafana 监控的完整过程,命令均经实际执行验证。