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 监控的完整过程,命令均经实际执行验证。
浙公网安备 33010602011771号