pg_exporter 1.5.0 常用 CLI 命令与工具详解

pg_exporter 1.5.0 命令行使用与运行期管理全解:主命令 22 个 flags 的 --help 逐行实测与 PG_EXPORTER_* 环境变量对照、-E/-D 诊断参数组合实例、HTTP 端点族 curl 实测(/metrics /stat /reload /health)、Release tarball + systemd 服务 0→1 部署(status/journalctl 回显照抄)与 6 条真实排障实录。

pg_exporterPostgreSQLPrometheusGolang数据库监控2026/11/01

pg_exporter 1.5.0 常用 CLI 命令与工具详解

目标:把 pg_exporter 1.5.0 的命令行使用方式一次讲全:唯一主命令与全部 22 个启动 flags(--help 实测逐行照抄)、flags 与 PG_EXPORTER_* 环境变量的对照关系、-E/-D 两个诊断参数的输出解读、HTTP 端点族(/metrics、/stat、/reload 等)的 curl 实测,以及 Release tarball 二进制 + systemd 服务的 0→1 生产部署(systemctl status/journalctl 回显照抄)。全部命令输出均为真实回显,排障章节的报错与退出码均来自真实触发。

一、环境信息

本文所有命令与回显均在以下环境实测(版本复核日期 2026-11-01):

  • 操作系统:Ubuntu 24.04.5 LTS(x86_64,主机名 pgexporter-server,systemd 255 (255.4-1ubuntu8.18))
  • pg_exporter:1.5.0(GitHub Release tarball pg_exporter-1.5.0.linux-amd64.tar.gz,--version 实测回显 pg_exporter v1.5.0 (built with go1.27.3 on linux/amd64);最新稳定版经 shields.io release 徽章复核仍为 v1.5.0,查询日期 2026-11-01,与本文版本一致)
  • 被监控数据库:PostgreSQL 16.15(官方 postgres:16 镜像容器,服务器内网主机名 pg16-db:5432;库内含 dbtest 演示库与 db1/db2 两个空库)
  • 监控账号:dbuser_monitor / q1w2e3r4(PostgreSQL 内置 pg_monitor 角色,授权方法见部署篇 4.2 节)
  • 采集端口:9630(pg_exporter 固定默认监听端口)
  • 服务器登录账号:root

pg_exporter 是 Go 编写、YAML 声明式驱动的 PostgreSQL/PgBouncer Prometheus 指标采集器。项目认知与同类选型对比见 《pg_exporter 1.5.0 介绍与选型指南》;本文的姊妹篇:Compose 双容器部署见 《pg_exporter 1.5.0 Docker Compose 部署指南》,YAML 配置文件层的字段语义见 《pg_exporter 1.5.0 配置参数详解》。三篇分工一句话:选型看 A1、部署看 B2、指标怎么定义看 C1、进程怎么跑看本文。

二、工具概览

pg_exporter 把"CLI 体系"收敛到了极致——只有一个二进制、一条主命令,没有子命令。日常使用围绕四类工具展开:

工具角色本文章节
pg_exporter主命令:启动采集进程,全部行为由 22 个启动 flags + PG_EXPORTER_* 环境变量决定4.1、4.2
HTTP 端点族运行期管理接口:抓取指标、查统计、热重载配置、健康探测4.3
systemctl生产托管:开机自启、崩溃自动拉起(官方随附 unit 文件)4.4
journalctl日志检索:启动日志、采集报错、连接失败都从这里查4.4、六

22 个 flags 的分组速览(完整清单与逐行 --help 回显见 4.1 节):

分组flags一句话职责
连接目标-u/--url、-T/--connect-timeout、-f/--fail-fast指定监控哪个 PostgreSQL/PgBouncer、连不上怎么办
配置来源-c/--config采集器定义文件(或目录)
Web 端点--web.listen-address、-P/--web.telemetry-path、--web.config.file、--web.systemd-socket指标端点的地址、路径与 TLS/认证
标签与命名-l/--label、-t/--tag、-n/--namespace常量标签、调度标签、指标前缀
发现纳管-a/--auto-discovery、-x/--exclude-database、-i/--include-database多库实例自动纳管与排除
行为开关-C/--disable-cache、-m/--disable-intro强制绕过 TTL 缓存、只暴露查询指标
诊断-D/--dry-run、-E/--explain打印原始配置、解释规划结果(不启动服务)
日志--log.level、--log.formatdebug/info/warn/error、logfmt/json
元信息-h/--help、--version帮助与版本

💡 技术拓展:与 postgres_exporter 等同类的"启动参数 + 配置文件"双层设计不同,pg_exporter 的 flags 只管进程级行为(连谁、监听哪、日志几级),指标本体 100% 在 YAML 里——96 条采集分支、460 个指标全部由配置文件驱动,这就是它能把配置做成"数据面/控制面分离"的原因,字段级语义见 《pg_exporter 1.5.0 配置参数详解》。

三、前置条件

跟读本文实测操作前,需要具备:

  1. 一台可 SSH 登录的 Linux 服务器(本文为 Ubuntu 24.04,root 账号)与一个可访问的 PostgreSQL 实例(本文为内网 pg16-db:5432 的 PG 16.15);如果手头没有现成数据库,可按 《pg_exporter 1.5.0 Docker Compose 部署指南》 第四章一键拉起含演示数据的双容器栈。
  2. 监控账号:dbuser_monitor(已授予 pg_monitor 角色),与部署篇一致。
  3. curl:下载 Release 包与验证 HTTP 端点用(Ubuntu 24.04 自带)。
  4. systemd:systemd 部署实测章节需要(容器演练时按本文 4.4 的 Ubuntu 24.04 基础镜像即可)。

四、各工具详解

4.1 主命令 pg_exporter 与全局 flags

4.1.1 --version 与 --help 实测

先确认二进制版本(安装步骤见 4.4 节):

root@pgexporter-server:~# pg_exporter --version
pg_exporter v1.5.0 (built with go1.27.3 on linux/amd64)

再来看 v1.5.0 的完整帮助——这就是本文所有 flags 语义的权威依据(逐行实测回显):

root@pgexporter-server:~# pg_exporter --help
usage: pg_exporter [<flags>]


Flags:
  -h, --[no-]help                Show context-sensitive help (also try
                                 --help-long and --help-man).
  -u, --url=URL                  postgres target url
  -c, --config=CONFIG            path to config dir or file
      --[no-]web.systemd-socket  Use systemd socket activation listeners instead
                                 of port listeners (Linux only).
      --web.listen-address=:9630 ...  
                                 Addresses on which to expose metrics and web
                                 interface. Repeatable for multiple addresses.
                                 Examples: `:9100` or `[::1]:9100` for http,
                                 `vsock://:9100` for vsock
      --web.config.file=""       Path to configuration file that can
                                 enable TLS or authentication. See:
                                 https://github.com/prometheus/exporter-toolkit/blob/master/docs/web-configuration.md
  -l, --label=""                 constant labels: comma separated list of
                                 label=value pair ($PG_EXPORTER_LABEL)
  -t, --tag=""                   tags,comma separated list of server tag
                                 ($PG_EXPORTER_TAG)
  -C, --[no-]disable-cache       force not using cache
                                 ($PG_EXPORTER_DISABLE_CACHE)
  -m, --[no-]disable-intro       disable internal/exporter self
                                 metrics (only expose query metrics)
                                 ($PG_EXPORTER_DISABLE_INTRO)
  -a, --[no-]auto-discovery      automatically scrape all database for given
                                 server ($PG_EXPORTER_AUTO_DISCOVERY)
  -x, --exclude-database="template0,template1,postgres"  
                                 excluded databases when enabling auto-discovery
                                 ($PG_EXPORTER_EXCLUDE_DATABASE)
  -i, --include-database=""      included databases when enabling auto-discovery
                                 ($PG_EXPORTER_INCLUDE_DATABASE)
  -n, --namespace=""             prefix of built-in metrics, (pg|pgbouncer) by
                                 default ($PG_EXPORTER_NAMESPACE)
  -f, --[no-]fail-fast           fail fast instead of waiting during start-up
                                 ($PG_EXPORTER_FAIL_FAST)
  -T, --connect-timeout=100      connect timeout in ms, 100 by default
                                 ($PG_EXPORTER_CONNECT_TIMEOUT)
  -P, --web.telemetry-path="/metrics"  
                                 URL path under which to expose metrics.
                                 ($PG_EXPORTER_TELEMETRY_PATH)
  -D, --[no-]dry-run             dry run and print raw configs
  -E, --explain             explain server planned queries
      --log.level="info"         log level: debug|info|warn|error
      --log.format="logfmt"      log format: logfmt|json
      --[no-]version             Show application version.

逐行照抄时请注意三个容易误读的细节:

  • 没有 -d(daemonize)参数。v1.5.0 不提供守护进程化 flag,官方形态就是前台运行 + systemd 托管(见 4.4 节)。
  • 监听地址参数叫 --web.listen-address,不叫 --listen;默认值 :9630,支持重复传参监听多个地址(如同时绑 IPv4/IPv6)。
  • 帮助文本里 ($PG_EXPORTER_XXX) 标注的是该 flag 对应的环境变量——同一能力有两个入口,这是 systemd 部署的注入通道(对照表见 4.1.3)。

4.1.2 常用 flags 逐项详解

结合实测行为,把最容易用错/最常用的 flags 展开讲:

flag默认值详解(均为实测结论)
-u, --url无(回退 postgresql:///?sslmode=disable,触发 WARN,见 6.6)监控目标连接串。主库场景一般指向 postgres 库;URL 里只写一个库,其余库靠 auto-discovery 纳管(4.2 实例 1 的日志可见:URL 指向 dbtest,db1/db2 被自动发现并 spawn)。日志中密码段自动打码为 xxxxx
-c, --config五级探测(--config > PG_EXPORTER_CONFIG > ./pg_exporter.yml > /etc/pg_exporter.yml > /etc/pg_exporter/)采集器定义,文件或目录均可;目录时按文件名字母序合并。五级探测顺序与目录合并规则见 《pg_exporter 1.5.0 配置参数详解》 3.1 节
--web.listen-address:9630监听地址。公网部署时建议 127.0.0.1:9630(仅本机 Prometheus 抓取)或配 TLS/Basic Auth(--web.config.file)
-l, --label空常量标签,k1=v1,k2=v2 形式,会附加到所有指标上,多实例汇总时用于区分来源
-t, --tag空给 exporter 本身打标签,是采集器 tags 调度机制的匹配对象:配置里 tags: [cluster] 的采集器只有在 exporter 被 -t cluster 标记后才会安装
-C, --disable-cachefalse强制每次抓取都真实执行 SQL、绕过 TTL 缓存,排查"指标怎么不更新"时的一键开关
-m, --disable-introfalse只暴露查询指标,隐藏 go_*/process_* 等 exporter 自我观测指标(本文 /metrics 共 2043 行,含大量 go_*)
-a, --auto-discoveryfalse(env 默认 true)自动发现并纳管实例上所有库(排除 -x 名单);单库监控无需开启
-x, --exclude-databasetemplate0,template1,postgres自动发现黑名单。注意 postgres 默认在名单里——想让 URL 主库之外的 postgres 库也被纳管需要显式调整
-i, --include-database空自动发现白名单,设置后只纳管名单内的库
-n, --namespacepg(pgbouncer 场景 pgbouncer)内置指标前缀,同一 Prometheus 里区分多套 exporter 时用
-f, --fail-fastfalse启动时连不上库:默认继续启动反复重试(日志明确打 (startup will continue)),-f 则直接退出(exit=2),两者实测对照见 6.4
-T, --connect-timeout100(毫秒)建连超时,跨机房/高延迟网络适当调大
-P, --web.telemetry-path/metrics指标端点路径,反向代理场景按需改
-D, --dry-runfalse加载并打印解析后的配置(man 风格排版),不连库、不启动,配置分发前的预检工具(实测见 4.2 实例 3)
-E, --explainfalse连库执行规划过程后解释每个采集器"装没装、为什么",排配置调度问题的利器(实测见 4.2 实例 2)
--log.levelinfodebug 会额外输出 load 96 queries from ...、check primary server connectivity 等过程行
--log.formatlogfmt可选 json,接日志采集系统时用
--web.config.file空Prometheus exporter-toolkit 格式的 Web 配置,可启用 TLS 与 Basic Auth
--web.systemd-socketfalsesystemd socket activation 接管监听(Linux only),深度 systemd 集成场景用

4.1.3 flags 与 PG_EXPORTER_* 环境变量对照

--help 回显中每个 ($PG_EXPORTER_XXX) 标注就是官方约定的环境变量入口,与官方随附环境文件 /etc/default/pg_exporter 一一对应:

环境变量等价 flag环境文件实测默认值
PG_EXPORTER_URL-u/--url'postgres://:5432/postgres?sslmode=disable'(需改为实际目标)
PG_EXPORTER_CONFIG-c/--config/etc/pg_exporter.yml
PG_EXPORTER_LABEL-l/--label""
PG_EXPORTER_TAG-t/--tag""
PG_EXPORTER_DISABLE_CACHE-C/--disable-cachefalse
PG_EXPORTER_DISABLE_INTRO-m/--disable-intro(环境文件未列,按需追加)
PG_EXPORTER_AUTO_DISCOVERY-a/--auto-discoverytrue
PG_EXPORTER_EXCLUDE_DATABASE-x/--exclude-database"template0,template1,postgres"
PG_EXPORTER_INCLUDE_DATABASE-i/--include-database""
PG_EXPORTER_NAMESPACE-n/--namespace"pg"
PG_EXPORTER_FAIL_FAST-f/--fail-fastfalse
PG_EXPORTER_CONNECT_TIMEOUT-T/--connect-timeout100
PG_EXPORTER_TELEMETRY_PATH-P/--web.telemetry-path"/metrics"

两条入口的选择原则(实测佐证):

  • 优先级:命令行 flag > 环境变量。实测中 -u 从命令行传入时启动日志打印 retrieve target url ... from command line,从环境文件注入时打印 retrieve target url ... from PG_EXPORTER_URL——来源一目了然,排查"参数为什么不生效"先看这行。
  • 没有环境变量对应的参数(--web.listen-address、--log.level、--log.format 等)在 systemd 下通过 unit 文件里的 $PG_EXPORTER_OPTS 注入(见 4.4.6)。

4.2 启动参数组合实例

实例 1:最小前台启动(调试标配)

root@pgexporter-server:~# pg_exporter -c /etc/pg_exporter.yml \
    -u 'postgres://dbuser_monitor:q1w2e3r4@pg16-db:5432/dbtest?sslmode=disable' \
    --web.listen-address=127.0.0.1:9631 --log.level=debug

启动日志实测回显(--log.level=debug 比 info 多出 DEBUG 过程行):

time=2026-11-01T03:54:42.594Z level=DEBUG msg="init pg_exporter, configPath=/etc/pg_exporter.yml constLabels= disableCache=false autoDiscovery=true excludeDatabase=template0,template1,postgres includeDatabase= connectTimeout=100ms webConfig=[127.0.0.1:9631] metricPath=/metrics"
time=2026-11-01T03:54:42.595Z level=INFO msg="retrieve target url postgres://dbuser_monitor:xxxxx@pg16-db:5432/dbtest?sslmode=disable from command line"
time=2026-11-01T03:54:42.595Z level=INFO msg="retrieve config path /etc/pg_exporter.yml from command line"
time=2026-11-01T03:54:42.607Z level=DEBUG msg="load 96 queries from /etc/pg_exporter.yml"
time=2026-11-01T03:54:42.607Z level=DEBUG msg="exporter init with 96 queries"
time=2026-11-01T03:54:42.608Z level=INFO msg="auto discovery is enabled, excludeDatabase=map[postgres:true template0:true template1:true], includeDatabase=map[]"
time=2026-11-01T03:54:42.608Z level=DEBUG msg="check primary server connectivity"
time=2026-11-01T03:54:42.613Z level=INFO msg="server [dbtest] version changed: from [0] to [160015]"
time=2026-11-01T03:54:42.613Z level=DEBUG msg="server [dbtest] found new database postgres"
time=2026-11-01T03:54:42.613Z level=DEBUG msg="server [dbtest] found new database db1"
time=2026-11-01T03:54:42.613Z level=DEBUG msg="server [dbtest] found new database db2"
time=2026-11-01T03:54:42.613Z level=DEBUG msg="server [dbtest] auto discovery database list change : map[db1:true db2:true postgres:true]"
time=2026-11-01T03:54:42.613Z level=INFO msg="skip database change: add postgres according to in excluded database list"
time=2026-11-01T03:54:42.613Z level=INFO msg="spawn new server for database db1 : postgres://dbuser_monitor:xxxxx@pg16-db:5432/db1?sslmode=disable"
time=2026-11-01T03:54:42.613Z level=INFO msg="database db1 is installed due to auto-discovery"
time=2026-11-01T03:54:42.613Z level=INFO msg="spawn new server for database db2 : postgres://dbuser_monitor:xxxxx@pg16-db:5432/db2?sslmode=disable"
time=2026-11-01T03:54:42.613Z level=INFO msg="database db2 is installed due to auto-discovery"
time=2026-11-01T03:54:42.614Z level=INFO msg="pg_exporter for postgres://dbuser_monitor:xxxxx@pg16-db:5432/dbtest?sslmode=disable start, listen on 127.0.0.1:9631/metrics"
time=2026-11-01T03:54:42.614Z level=INFO msg="Listening on" address=127.0.0.1:9631
time=2026-11-01T03:54:42.614Z level=INFO msg="TLS is disabled." http2=false address=127.0.0.1:9631

这段日志信息量很大:第一行 init pg_exporter 回显了全部生效参数(排配置问题的第一现场);load 96 queries 确认全量配置加载成功;URL 指向 dbtest 但 db1/db2 仍被自动发现,postgres 库则因命中排除名单被跳过(skip database change: add postgres according to in excluded database list)。

实例 2:-E 解释规划结果(配置调度排障利器)

用部署篇的自定义采集器配置(2 条业务采集器 + 热重载实验加的 demo_uptime,共 3 条)实测 -E:

root@pgexporter-server:~# pg_exporter -c /tmp/demo.yml \
    -u 'postgres://dbuser_monitor:q1w2e3r4@pg16-db:5432/dbtest?sslmode=disable' -E

输出实测回显(head -25 节选,man 风格排版):

time=2026-11-01T03:55:19.815Z level=INFO msg="retrieve target url postgres://dbuser_monitor:xxxxx@pg16-db:5432/dbtest?sslmode=disable from command line"
time=2026-11-01T03:55:19.815Z level=INFO msg="retrieve config path /tmp/demo.yml from command line"
time=2026-11-01T03:55:19.816Z level=INFO msg="auto discovery is enabled, excludeDatabase=map[postgres:true template0:true template1:true], includeDatabase=map[]"
time=2026-11-01T03:55:19.819Z level=INFO msg="server [dbtest] version changed: from [0] to [160015]"
time=2026-11-01T03:55:19.820Z level=INFO msg="skip database change: add postgres according to in excluded database list"
time=2026-11-01T03:55:19.820Z level=INFO msg="spawn new server for database db1 : postgres://dbuser_monitor:xxxxx@pg16-db:5432/db1?sslmode=disable"
time=2026-11-01T03:55:19.820Z level=INFO msg="database db1 is installed due to auto-discovery"
time=2026-11-01T03:55:19.820Z level=INFO msg="spawn new server for database db2 : postgres://dbuser_monitor:xxxxx@pg16-db:5432/db2?sslmode=disable"
time=2026-11-01T03:55:19.820Z level=INFO msg="database db2 is installed due to auto-discovery"
time=2026-11-01T03:55:19.820Z level=INFO msg="server [dbtest] planned with 3 queries, 3 installed, 0 discarded, installed: demo_orders_stat, demo_db_size, demo_uptime , discarded: "
##
# SYNOPSIS
#       demo_orders.demo_orders_stat_*
#
# DESCRIPTION
#       demo business table statistics (dbtest only)
#
# OPTIONS
#       Tags       [dbname:dbtest]
#       TTL        5
#       Priority   0
#       Timeout    1s
#       Fatal      false
#       Version    lower ~ higher
#       Source     demo.yml

解读:planned with 3 queries, 3 installed, 0 discarded 一行是规划结论总账——**installed(已安装)与 discarded(因版本/tags 不匹配被丢弃)**是判断"采集器为什么没出指标"的钥匙;随后每个采集器一块 man 风格说明,Tags [dbname:dbtest]、TTL 5 等字段与 YAML 定义一一对应。tags 调度机制的完整规则见 《pg_exporter 1.5.0 配置参数详解》 5.5 节。

实例 3:-D 预检配置文件(不连库)

root@pgexporter-server:~# pg_exporter -c /tmp/demo.yml -D

输出实测回显(head -20 节选):

time=2026-11-01T03:55:20.876Z level=WARN msg="fail retrieving target url, fallback on default url: postgresql:///?sslmode=disable"
time=2026-11-01T03:55:20.876Z level=INFO msg="retrieve config path /tmp/demo.yml from command line"
##
# SYNOPSIS
#       demo_orders.demo_orders_stat_*
#
# DESCRIPTION
#       demo business table statistics (dbtest only)
#
# OPTIONS
#       Tags       [dbname:dbtest]
#       TTL        5
#       Priority   0
#       Timeout    1s
#       Fatal      false
#       Version    lower ~ higher
#       Source     demo.yml
#
# METRICS
#       rows (GAUGE)

-D 连库都不需要(第一行 WARN 是没传 -u 时的回退提示,见 6.6),打印的是解析后的配置清单——分发配置前先 -D 一遍,YAML 语法错、字段名拼错当场现形(真实报错样例见 6.1/6.2)。# METRICS 段列出该采集器产出的指标列(rows (GAUGE))。

实例 4:systemd 环境变量注入组合

生产部署不敲一长串 flags,而是用官方随附的 /etc/default/pg_exporter 环境文件(安装与修改过程见 4.4.5),本文实测的最终内容:

PG_EXPORTER_URL='postgres://dbuser_monitor:q1w2e3r4@pg16-db:5432/postgres?sslmode=disable'
PG_EXPORTER_CONFIG=/etc/pg_exporter.yml
PG_EXPORTER_LABEL=""
PG_EXPORTER_TAG=""
PG_EXPORTER_DISABLE_CACHE=false
PG_EXPORTER_AUTO_DISCOVERY=true
PG_EXPORTER_EXCLUDE_DATABASE="template0,template1,postgres"
PG_EXPORTER_INCLUDE_DATABASE=""
PG_EXPORTER_NAMESPACE="pg"
PG_EXPORTER_FAIL_FAST=false
PG_EXPORTER_CONNECT_TIMEOUT=100
PG_EXPORTER_TELEMETRY_PATH="/metrics"
PG_EXPORTER_OPTS='--log.level=info'

前 12 行与 4.1.3 对照表一一对应,最后一行 PG_EXPORTER_OPTS 是 unit 文件的"兜底参数位"——没有独立环境变量的 flags 都塞这里。组合效果:环境文件负责"连谁、用什么配置",PG_EXPORTER_OPTS 负责"日志几级",零 flags 敲进命令行。

4.3 HTTP 端点族

pg_exporter 运行后暴露一组 HTTP 端点,全部实测(服务为 4.4 节 systemd 实例,监听 :9630):

端点方法用途实测响应
/metricsGETPrometheus 抓取的指标本体HTTP 200,2043 行
/upGET目标存活探测HTTP 200,primary
/healthGET健康检查HTTP 200,primary
/livenessGET存活探针(K8s liveness 语义)HTTP 200,primary
/readinessGET就绪探针(K8s readiness 语义)HTTP 200,primary
/reloadPOST热重载配置文件(不重启进程)HTTP 200,server reloaded
/statGET采集器命中/耗时统计表HTTP 200,见下文

4.3.1 健康探测端点实测

root@pgexporter-server:~# for p in up health liveness readiness; do
>   echo "=== GET /$p ==="; curl -si http://localhost:9630/$p; echo
> done
=== GET /up ===
HTTP/1.1 200 OK
Content-Type: text/plain; charset=utf-8
Date: Sun, 01 Nov 2026 03:53:54 GMT
Content-Length: 7

primary
=== GET /health ===
HTTP/1.1 200 OK
Content-Type: text/plain; charset=utf-8
Date: Sun, 01 Nov 2026 03:53:54 GMT
Content-Length: 7

primary
=== GET /liveness ===
HTTP/1.1 200 OK
Content-Type: text/plain; charset=utf-8
Date: Sun, 01 Nov 2026 03:53:54 GMT
Content-Length: 7

primary
=== GET /readiness ===
HTTP/1.1 200 OK
Content-Type: text/plain; charset=utf-8
Date: Sun, 01 Nov 2026 03:53:54 GMT
Content-Length: 7

primary

四个端点全部返回 HTTP 200 与当前实例角色 primary(本文目标是主库;容器编排里最实用的是 /health 与 /readiness,部署篇 5.2 节的 healthcheck 即基于 /health)。

4.3.2 POST /reload 热重载实测

修改配置文件后无需重启进程,一行 curl 生效:

root@pgexporter-server:~# curl -si -XPOST http://localhost:9630/reload
HTTP/1.1 200 OK
Content-Type: text/plain; charset=utf-8
Date: Sun, 01 Nov 2026 03:53:55 GMT
Content-Length: 15

server reloaded

完整热重载闭环实验(追加采集器 → reload → 新指标出现,含 server reloaded, 3 queries applied 日志)见 《pg_exporter 1.5.0 Docker Compose 部署指南》 8.2 节。

4.3.3 GET /stat 采集统计实测

/stat 返回每个已安装采集器的命中统计(进程刚启动、尚未抓取时只有表头):

root@pgexporter-server:~# curl -s http://localhost:9630/stat
name                     total      hit        error      skip       metric     ttl/s  duration/ms

触发一次抓取(curl -s http://localhost:9630/metrics > /dev/null)后再查,完整输出如下(38 个已安装采集器逐行统计):

root@pgexporter-server:~# curl -s http://localhost:9630/stat
name                     total      hit        error      skip       metric     ttl/s  duration/ms
pg_wait                  3          1          0          0          5          10     0.983044  
pg_checkpoint            3          2          0          0          19         18     0.170212  
pg_xact                  3          1          0          0          3          10     0.221252  
pg_db                    3          1          0          0          210        10     0.643708  
pg_meta                  3          1          0          0          1          10     0.226214  
pg_backend               3          1          0          0          6          10     0.414409  
pg_indexing              3          1          0          0          0          10     0.459329  
pg_sub                   3          1          0          0          0          10     0.474283  
pg_lock                  3          1          0          0          32         10     0.433323  
pg_index                 3          1          0          0          0          10     1.789023  
pg_subrel                3          1          0          0          0          10     0.303548  
pg_table_size            3          2          0          0          0          258    0.290646  
pg_downstream            3          1          0          0          5          10     0.627097  
pg_size                  3          2          0          0          8          18     3.185335  
pg_xact_age              3          1          0          0          0          10     0.483485  
pg_clustering            3          1          0          0          0          10     0.300642  
pg_relkind               3          2          0          0          4          18     0.255440  
pg_slot                  3          1          0          0          0          10     0.465678  
pg_wal                   3          1          0          0          9          10     0.191273  
pg_defpart               3          2          0          0          0          18     0.183079  
pg_timeline              3          1          0          0          1          10     0.281227  
pg_table                 3          1          0          0          0          10     2.106509  
pg_setting               3          1          0          0          36         10     0.430162  
pg_vacuuming             3          1          0          0          0          10     0.372146  
pg_backup                3          1          0          0          0          10     0.182301  
pg_sync_standby          3          1          0          0          1          10     0.158609  
pg_seq                   3          1          0          0          0          10     0.615303  
pg_io                    3          1          0          0          420        10     0.551758  
pg_slru                  3          2          0          0          64         18     0.402370  
pg_archiver              3          2          0          0          5          18     0.194059  
pg_pubrel                3          1          0          0          0          10     0.496555  
pg_func                  3          1          0          0          0          10     0.826942  
pg_activity              3          1          0          0          96         10     0.677783  
pg                       3          1          0          0          15         1      0.313123  
pg_repl                  3          1          0          0          0          10     0.488809  
pg_checkpointer          3          1          0          0          6          10     0.187419  
pg_ssl                   3          1          0          0          2          10     0.386609  
pg_bgwriter              3          1          0          0          11         10     0.216911  

列语义:total=抓取次数、hit=TTL 缓存命中数、error=执行失败数、skip=被调度跳过数、metric=该采集器产出指标数、ttl/s=缓存秒数、duration/ms=单次执行耗时。排障口诀:error 列非零查 SQL 与权限,metric 列为 0 查 tags 调度(对照 -E 输出定位)。

4.3.4 /metrics 指标端点实测

root@pgexporter-server:~# curl -s http://localhost:9630/metrics | head -45
# HELP go_gc_duration_seconds A summary of the wall-time pause (stop-the-world) duration in garbage collection cycles.
# TYPE go_gc_duration_seconds summary
go_gc_duration_seconds{quantile="0"} 8.5451e-05
go_gc_duration_seconds{quantile="0.25"} 0.000101596
go_gc_duration_seconds{quantile="0.5"} 0.000179247
go_gc_duration_seconds{quantile="0.75"} 0.000186923
go_gc_duration_seconds{quantile="1"} 0.000250507
go_gc_duration_seconds_sum 0.000980618
go_gc_duration_seconds_count 6
# HELP go_gc_gogc_percent Heap size target percentage configured by the user, otherwise 100. This value is set by the GOGC environment variable, and the runtime/debug.SetGCPercent function. Sourced from /gc/gogc:percent.
# TYPE go_gc_gogc_percent gauge
go_gc_gogc_percent 100
# HELP go_gc_gomemlimit_bytes Go runtime memory limit configured by the user, otherwise math.MaxInt64. This value is set by the GOMEMLIMIT environment variable, and the runtime/debug.SetMemoryLimit function. Sourced from /gc/gomemlimit:bytes.
# TYPE go_gc_gomemlimit_bytes gauge
go_gc_gomemlimit_bytes 9.223372036854776e+18
# HELP go_goroutines Number of goroutines that currently exist.
# TYPE go_goroutines gauge
go_goroutines 20
# HELP go_info Information about the Go environment.
# TYPE go_info gauge
go_info{version="go1.27.3"} 1
# HELP go_memstats_alloc_bytes Number of bytes allocated in heap and currently in use. Equals to /memory/classes/heap/objects:bytes.
# TYPE go_memstats_alloc_bytes gauge
go_memstats_alloc_bytes 5.592672e+06
# HELP go_memstats_alloc_bytes_total Total number of bytes allocated in heap until now, even if released already. Equals to /gc/heap/allocs:bytes.
# TYPE go_memstats_alloc_bytes_total counter
go_memstats_alloc_bytes_total 1.2439096e+07
# HELP go_memstats_buck_hash_sys_bytes Number of bytes used by the profiling bucket hash table. Equals to /memory/classes/profiling/buckets:bytes.
# TYPE go_memstats_buck_hash_sys_bytes gauge
go_memstats_buck_hash_sys_bytes 1.444448e+06
# HELP go_memstats_frees_total Number of heap objects frees. Equals to /gc/heap/frees:objects + /gc/heap/tiny/allocs:objects.
# TYPE go_memstats_frees_total counter
go_memstats_frees_total 123286
# HELP go_memstats_gc_sys_bytes Number of bytes used for garbage collection system metadata. Equals to /memory/classes/metadata/other:bytes.
# TYPE go_memstats_gc_sys_bytes gauge
go_memstats_gc_sys_bytes 3.281648e+06
# HELP go_memstats_heap_alloc_bytes Number of heap bytes allocated and currently in use, same as go_memstats_alloc_bytes. Equals to /memory/classes/heap/objects:bytes.
# TYPE go_memstats_heap_alloc_bytes gauge
go_memstats_heap_alloc_bytes 5.592672e+06
# HELP go_memstats_heap_idle_bytes Number of heap bytes waiting to be used. Equals to /memory/classes/heap/released:bytes + /memory/classes/heap/free:bytes.
# TYPE go_memstats_heap_idle_bytes gauge
go_memstats_heap_idle_bytes 8.101888e+06
# HELP go_memstats_heap_inuse_bytes Number of heap bytes that are in use. Equals to /memory/classes/heap/objects:bytes + /memory/classes/heap/unused:bytes
# TYPE go_memstats_heap_inuse_bytes gauge
go_memstats_heap_inuse_bytes 7.757824e+06
...
root@pgexporter-server:~# curl -s http://localhost:9630/metrics | wc -l
2043

头部是 go_*/process_* 自我观测指标(不需要时 -m/--disable-intro 一键关闭),核心的 pg_* 业务指标在其中,用 grep 精准提取:

root@pgexporter-server:~# curl -s http://localhost:9630/metrics | grep -E '^pg_(up|exporter_build_info|version|in_recovery)'
pg_exporter_build_info{branch="HEAD",builddate="2026-10-23T01:33:50Z",goarch="amd64",goos="linux",goversion="go1.27.3",revision="1891254",version="v1.5.0"} 1
pg_in_recovery 0
pg_up 1
pg_uptime 4580.174507
pg_version 160015

pg_up 1(连库正常)、pg_version 160015(PG 16.15 的版本号编码)、pg_in_recovery 0(主库)——这三个指标是所有告警规则的基石;pg_exporter_build_info 还顺带记录了构建信息(revision 1891254、构建时间 2026-10-23)。

4.4 systemd 服务部署实测

裸二进制前台跑只适合调试,生产用 systemd 托管。本章从零开始完整走一遍(所有回显真实)。

4.4.1 下载与校验 Release 包

root@pgexporter-server:~# curl -fsSL -o /tmp/pg_exporter-1.5.0.linux-amd64.tar.gz \
    https://github.com/pgsty/pg_exporter/releases/download/v1.5.0/pg_exporter-1.5.0.linux-amd64.tar.gz
root@pgexporter-server:~# ls -l /tmp/pg_exporter-1.5.0.linux-amd64.tar.gz
-rw-r--r-- 1 root root 5672925 Nov  1 03:59 /tmp/pg_exporter-1.5.0.linux-amd64.tar.gz
root@pgexporter-server:~# sha256sum /tmp/pg_exporter-1.5.0.linux-amd64.tar.gz
e372f6defb844b4bfbe3286b40dba3d4aae2ce72c4bed9980e3b9a56507aef56  /tmp/pg_exporter-1.5.0.linux-amd64.tar.gz

哈希值与 Release 页官方 checksums.txt 一致,包体 5.6 MB。

4.4.2 解包

先看包内结构(没有顶层目录,文件直接散开,先看清楚再解包):

root@pgexporter-server:~# tar -tzf /tmp/pg_exporter-1.5.0.linux-amd64.tar.gz
LICENSE
package/pg_exporter.default
package/pg_exporter.service
pg_exporter.yml
pg_exporter
root@pgexporter-server:~# cd /tmp && tar -xzf pg_exporter-1.5.0.linux-amd64.tar.gz

5 个文件的用途:pg_exporter(主二进制)、pg_exporter.yml(官方全量采集器配置,237 KB/96 条采集分支)、package/pg_exporter.service(systemd unit)、package/pg_exporter.default(环境文件模板)、LICENSE(Apache-2.0)。

4.4.3 安装二进制并验证

root@pgexporter-server:/tmp# install -m 0755 pg_exporter /usr/bin/pg_exporter
root@pgexporter-server:/tmp# pg_exporter --version
pg_exporter v1.5.0 (built with go1.27.3 on linux/amd64)

4.4.4 创建 prometheus 系统用户

unit 文件以 User=prometheus 运行,先建号(系统用户、禁止登录):

root@pgexporter-server:/tmp# useradd -r -s /usr/sbin/nologin prometheus
root@pgexporter-server:/tmp# id prometheus
uid=997(prometheus) gid=997(prometheus) groups=997(prometheus)

4.4.5 安装配置文件与环境文件

root@pgexporter-server:/tmp# install -m 0644 pg_exporter.yml /etc/pg_exporter.yml
root@pgexporter-server:/tmp# install -m 0644 package/pg_exporter.default /etc/default/pg_exporter

环境文件模板里的 PG_EXPORTER_URL 是空目标占位(postgres://:5432/postgres?sslmode=disable),替换为实际数据库地址(本文用 vi 编辑,也可 sed):

PG_EXPORTER_URL='postgres://dbuser_monitor:q1w2e3r4@pg16-db:5432/postgres?sslmode=disable'

改完的完整文件内容见 4.2 实例 4。这一行是整个部署唯一必须修改的地方。

4.4.6 安装 systemd unit 文件

root@pgexporter-server:/tmp# install -m 0644 package/pg_exporter.service /etc/systemd/system/pg_exporter.service

官方 unit 文件全文:

[Unit]
Description=Prometheus exporter for PostgreSQL/Pgbouncer server metrics
Documentation=https://pigsty.io/docs/pg_exporter
After=network.target

[Service]
EnvironmentFile=-/etc/default/pg_exporter
User=prometheus
ExecStart=/usr/bin/pg_exporter $PG_EXPORTER_OPTS
Restart=on-failure

[Install]
WantedBy=multi-user.target

逐行解读:EnvironmentFile=- 前缀的减号表示文件缺失不报错(此时进程直接读不到 PG_EXPORTER_URL 等变量,回退默认值启动,见 6.6);ExecStart 只带 $PG_EXPORTER_OPTS 一个变量——URL/CONFIG 等由进程直接从环境读取,flags 类参数走 PG_EXPORTER_OPTS;Restart=on-failure 保证异常退出自动拉起。

4.4.7 启动并设置开机自启

root@pgexporter-server:/tmp# systemctl daemon-reload
root@pgexporter-server:/tmp# systemctl enable --now pg_exporter
Created symlink /etc/systemd/system/multi-user.target.wants/pg_exporter.service → /etc/systemd/system/pg_exporter.service.
root@pgexporter-server:/tmp# systemctl is-active pg_exporter
active

enable --now 一步完成"开机自启 + 立即启动"。

4.4.8 状态与日志实测

root@pgexporter-server:/tmp# systemctl status pg_exporter --no-pager -l
● pg_exporter.service - Prometheus exporter for PostgreSQL/Pgbouncer server metrics
     Loaded: loaded (/etc/systemd/system/pg_exporter.service; enabled; preset: enabled)
     Active: active (running) since Sun 2026-11-01 03:53:36 UTC; 6s ago
       Docs: https://pigsty.io/docs/pg_exporter
   Main PID: 260 (pg_exporter)
      Tasks: 9 (limit: 2266)
     Memory: 7.9M (peak: 8.8M)
        CPU: 21ms
     CGroup: /system.slice/docker-c6eaa5394d52e0740fcac0e6a43fd3c97cd08bc264de0edc4bdbde3b6a92f1b4.scope/system.slice/pg_exporter.service
             └─260 /usr/bin/pg_exporter --log.level=info

Nov 01 03:53:36 pgexporter-server pg_exporter[260]: time=2026-11-01T03:53:36.597Z level=INFO msg="server [postgres] version changed: from [0] to [160015]"
Nov 01 03:53:36 pgexporter-server pg_exporter[260]: time=2026-11-01T03:53:36.604Z level=INFO msg="spawn new server for database dbtest : postgres://dbuser_monitor:xxxxx@pg16-db:5432/dbtest?sslmode=disable"
Nov 01 03:53:36 pgexporter-server pg_exporter[260]: time=2026-11-01T03:53:36.604Z level=INFO msg="database dbtest is installed due to auto-discovery"
Nov 01 03:53:36 pgexporter-server pg_exporter[260]: time=2026-11-01T03:53:36.604Z level=INFO msg="spawn new server for database db1 : postgres://dbuser_monitor:xxxxx@pg16-db:5432/db1?sslmode=disable"
Nov 01 03:53:36 pgexporter-server pg_exporter[260]: time=2026-11-01T03:53:36.604Z level=INFO msg="database db1 is installed due to auto-discovery"
Nov 01 03:53:36 pgexporter-server pg_exporter[260]: time=2026-11-01T03:53:36.604Z level=INFO msg="spawn new server for database db2 : postgres://dbuser_monitor:xxxxx@pg16-db:5432/db2?sslmode=disable"
Nov 01 03:53:36 pgexporter-server pg_exporter[260]: time=2026-11-01T03:53:36.604Z level=INFO msg="database db2 is installed due to auto-discovery"
Nov 01 03:53:36 pgexporter-server pg_exporter[260]: time=2026-11-01T03:53:36.604Z level=INFO msg="pg_exporter for postgres://dbuser_monitor:xxxxx@pg16-db:5432/postgres?sslmode=disable start, listen on :9630/metrics"
Nov 01 03:53:36 pgexporter-server pg_exporter[260]: time=2026-11-01T03:53:36.604Z level=INFO msg="Listening on" address=[::]:9630
Nov 01 03:53:36 pgexporter-server pg_exporter[260]: time=2026-11-01T03:53:36.604Z level=INFO msg="TLS is disabled." http2=false address=[::]:9630

内存 7.9 MB、9 个 task——资源占用几乎可以忽略。启动日志也可用 journalctl 完整回看:

root@pgexporter-server:/tmp# journalctl -u pg_exporter --no-pager -n 30
Nov 01 03:53:36 pgexporter-server systemd[1]: Started pg_exporter.service - Prometheus exporter for PostgreSQL/Pgbouncer server metrics.
Nov 01 03:53:36 pgexporter-server pg_exporter[260]: time=2026-11-01T03:53:36.584Z level=INFO msg="retrieve target url postgres://dbuser_monitor:xxxxx@pg16-db:5432/postgres?sslmode=disable from PG_EXPORTER_URL"
Nov 01 03:53:36 pgexporter-server pg_exporter[260]: time=2026-11-01T03:53:36.584Z level=INFO msg="retrieve config path /etc/pg_exporter.yml from PG_EXPORTER_CONFIG"
Nov 01 03:53:36 pgexporter-server pg_exporter[260]: time=2026-11-01T03:53:36.594Z level=INFO msg="auto discovery is enabled, excludeDatabase=map[postgres:true template0:true template1:true], includeDatabase=map[]"
Nov 01 03:53:36 pgexporter-server pg_exporter[260]: time=2026-11-01T03:53:36.597Z level=INFO msg="server [postgres] version changed: from [0] to [160015]"
Nov 01 03:53:36 pgexporter-server pg_exporter[260]: time=2026-11-01T03:53:36.604Z level=INFO msg="spawn new server for database dbtest : postgres://dbuser_monitor:xxxxx@pg16-db:5432/dbtest?sslmode=disable"
Nov 01 03:53:36 pgexporter-server pg_exporter[260]: time=2026-11-01T03:53:36.604Z level=INFO msg="database dbtest is installed due to auto-discovery"
Nov 01 03:53:36 pgexporter-server pg_exporter[260]: time=2026-11-01T03:53:36.604Z level=INFO msg="spawn new server for database db1 : postgres://dbuser_monitor:xxxxx@pg16-db:5432/db1?sslmode=disable"
Nov 01 03:53:36 pgexporter-server pg_exporter[260]: time=2026-11-01T03:53:36.604Z level=INFO msg="database db1 is installed due to auto-discovery"
Nov 01 03:53:36 pgexporter-server pg_exporter[260]: time=2026-11-01T03:53:36.604Z level=INFO msg="spawn new server for database db2 : postgres://dbuser_monitor:xxxxx@pg16-db:5432/db2?sslmode=disable"
Nov 01 03:53:36 pgexporter-server pg_exporter[260]: time=2026-11-01T03:53:36.604Z level=INFO msg="database db2 is installed due to auto-discovery"
Nov 01 03:53:36 pgexporter-server pg_exporter[260]: time=2026-11-01T03:53:36.604Z level=INFO msg="pg_exporter for postgres://dbuser_monitor:xxxxx@pg16-db:5432/postgres?sslmode=disable start, listen on :9630/metrics"
Nov 01 03:53:36 pgexporter-server pg_exporter[260]: time=2026-11-01T03:53:36.604Z level=INFO msg="Listening on" address=[::]:9630
Nov 01 03:53:36 pgexporter-server pg_exporter[260]: time=2026-11-01T03:53:36.604Z level=INFO msg="TLS is disabled." http2=false address=[::]:9630

注意前三行:retrieve target url ... from PG_EXPORTER_URL、retrieve config path ... from PG_EXPORTER_CONFIG——与 4.1.3 说的参数来源标识对应,systemd 注入时来源显示为环境变量名。

最后验证指标端点(pg_up 1 即部署成功):

root@pgexporter-server:/tmp# curl -s http://localhost:9630/metrics | grep -E '^pg_(up|exporter_build_info|version|in_recovery)'
pg_exporter_build_info{branch="HEAD",builddate="2026-10-23T01:33:50Z",goarch="amd64",goos="linux",goversion="go1.27.3",revision="1891254",version="v1.5.0"} 1
pg_in_recovery 0
pg_up 1
pg_uptime 4580.174507
pg_version 160015

4.4.9 日常服务管理

root@pgexporter-server:/tmp# systemctl restart pg_exporter && systemctl is-active pg_exporter
active

systemd 部署的常用运维命令清单:

命令用途
systemctl start/stop/restart pg_exporter启停与重启(改完环境文件必须 restart)
systemctl status pg_exporter状态、内存、最近日志
systemctl enable/disable pg_exporter开机自启开关
systemctl is-active pg_exporter脚本化状态判断(返回 active/inactive)
journalctl -u pg_exporter -f实时跟踪日志(排障首选)
journalctl -u pg_exporter -e看最近一次的日志尾部
curl -XPOST http://localhost:9630/reload只重载采集器配置,不重启进程

4.4.10 部署产物清单

root@pgexporter-server:/tmp# ls -l /usr/bin/pg_exporter /etc/pg_exporter.yml /etc/systemd/system/pg_exporter.service /etc/default/pg_exporter
-rw-r--r-- 1 root root      487 Nov  1 03:53 /etc/default/pg_exporter
-rw-r--r-- 1 root root   237291 Nov  1 03:48 /etc/pg_exporter.yml
-rw-r--r-- 1 root root      323 Nov  1 03:48 /etc/systemd/system/pg_exporter.service
-rwxr-xr-x 1 root root 14319776 Nov  1 03:48 /usr/bin/pg_exporter

四个文件、一条环境变量改动,就是全部部署足迹;卸载时删掉这四个文件再 systemctl disable pg_exporter 即可。

五、注意事项

  1. v1.5.0 没有守护进程化参数:--help 全量清单里没有 -d/--daemonize(4.1.1 实测为证),长驻运行的正解就是 4.4 的 systemd 托管;nohup pg_exporter & 属于应急手段,进程崩溃后无人拉起。
  2. 监听参数是 --web.listen-address,不是 --listen:网上旧资料里的 --listen 写法对 v1.5.0 无效,会直接报未知参数。
  3. flag 优先于环境变量:同一参数两处都配时以命令行为准(日志的 from command line/from PG_EXPORTER_URL 来源标识可自证,见 4.4.8);systemd 下只能走环境变量,所以要分清哪些参数有 env 名、哪些只能进 PG_EXPORTER_OPTS(4.1.3 对照表)。
  4. 环境文件含明文密码:/etc/default/pg_exporter 里的连接串是明文,建议收紧为 chown root:prometheus /etc/default/pg_exporter && chmod 640 /etc/default/pg_exporter;进程日志中密码段会自动打码为 xxxxx,不会泄进 journal。
  5. connect-timeout 单位是毫秒:-T 100 是 100 ms 而不是 100 s;跨机房高延迟链路按 RTT 的 5–10 倍设置。
  6. postgres 库默认被自动发现排除:-x 默认值含 postgres,URL 主库正常监控、但 postgres 库不会出现在 auto-discovery 名单(4.2 实例 1 日志实测);需要监控 postgres 库本身时调整 -x。
  7. /reload 只重载采集器配置:改 /etc/pg_exporter.yml 后 POST /reload 即可;但改 /etc/default/pg_exporter(连接串、自动发现等)必须 systemctl restart——环境变量是进程启动时读取的。
  8. --web.config.file 是生产公网部署的必选项:Exporter 默认无认证,仅监听 127.0.0.1 或放在内网安全组之后;需要直接暴露时用该参数配 TLS + Basic Auth(Prometheus exporter-toolkit 格式)。

六、常见问题与排障实录

以下案例全部在实测环境真实触发,退出码与报文均为真实回显。

6.1 配置文件 usage 拼写错误(exit=2)

# /tmp/bad.yml
bad_usage_collector:
  name: bad
  desc: bad usage demo
  query: |
    SELECT 1 AS v;
  metrics:
    - v:
        usage: FOO
        description: wrong usage
root@pgexporter-server:/tmp# pg_exporter -c /tmp/bad.yml -u 'postgres://dbuser_monitor:q1w2e3r4@pg16-db:5432/postgres?sslmode=disable' --web.listen-address=127.0.0.1:9631
time=2026-11-01T03:54:39.383Z level=INFO msg="retrieve target url postgres://dbuser_monitor:xxxxx@pg16-db:5432/postgres?sslmode=disable from command line"
time=2026-11-01T03:54:39.383Z level=INFO msg="retrieve config path /tmp/bad.yml from command line"
time=2026-11-01T03:54:39.384Z level=ERROR msg="fail creating pg_exporter: fail loading config file /tmp/bad.yml: query \"bad_usage_collector\" column \"v\" has unsupported usage: FOO"
root@pgexporter-server:/tmp# echo $?
2

usage 只有 GAUGE/COUNTER/LABEL/HISTOGRAM/DISCARD 五个合法取值,拼错在加载阶段就被拒绝(进程未启动,exit=2)。usage 五取值的语义见 《pg_exporter 1.5.0 配置参数详解》 5.4 节。

6.2 采集器缺 metrics 定义(exit=2)

# /tmp/bad2.yml
demo_broken:
  name: broken
  desc: yaml syntax error
  query: |
    SELECT 1 AS
  metrics: []
root@pgexporter-server:/tmp# pg_exporter -c /tmp/bad2.yml -u 'postgres://dbuser_monitor:q1w2e3r4@pg16-db:5432/postgres?sslmode=disable' --web.listen-address=127.0.0.1:9631
time=2026-11-01T03:54:41.192Z level=INFO msg="retrieve target url postgres://dbuser_monitor:xxxxx@pg16-db:5432/postgres?sslmode=disable from command line"
time=2026-11-01T03:54:41.192Z level=INFO msg="retrieve config path /tmp/bad2.yml from command line"
time=2026-11-01T03:54:41.192Z level=ERROR msg="fail creating pg_exporter: fail loading config file /tmp/bad2.yml: query \"demo_broken\" has no metrics definition"
root@pgexporter-server:/tmp# echo $?
2

两类配置错误都在启动瞬间报 fail creating pg_exporter: fail loading config file ...,报错信息精确到采集器名 + 列名,配合 4.2 实例 3 的 -D 预检可把问题拦截在分发前。

6.3 监听端口被占用(exit=1)

systemd 服务已在 :9630 运行时再启动第二个实例:

root@pgexporter-server:/tmp# pg_exporter -c /etc/pg_exporter.yml -u 'postgres://dbuser_monitor:q1w2e3r4@pg16-db:5432/postgres?sslmode=disable' --web.listen-address=:9630
time=2026-11-01T03:54:43.814Z level=INFO msg="spawn new server for database db2 : postgres://dbuser_monitor:xxxxx@pg16-db:5432/db2?sslmode=disable"
time=2026-11-01T03:54:43.814Z level=INFO msg="database db2 is installed due to auto-discovery"
time=2026-11-01T03:54:43.814Z level=INFO msg="pg_exporter for postgres://dbuser_monitor:xxxxx@pg16-db:5432/postgres?sslmode=disable start, listen on :9630/metrics"
time=2026-11-01T03:54:43.815Z level=ERROR msg="http server failed: listen tcp :9630: bind: address already in use"
root@pgexporter-server:/tmp# echo $?
1

注意与配置错误的区别:端口冲突在规划完成后才炸(日志先打完 spawn 过程),报 http server failed: ... address already in use,exit=1。排障口诀:报错在 fail loading config → 查配置;在 http server failed → 查端口(ss -ltnp | grep 9630)。

6.4 数据库不可达:默认等待 vs --fail-fast(exit 码对照)

目标指向一台没有 PG 的地址,默认模式(无 -f)——报错后照常启动、后台反复重试:

time=2026-11-01T03:55:18.045Z level=ERROR msg="fail connecting to primary server: fail fetching server version: dial tcp 127.0.0.1:5432: connect: connection refused (startup will continue)"
time=2026-11-01T03:55:18.045Z level=INFO msg="pg_exporter for postgres://dbuser_monitor:xxxxx@127.0.0.1:5432/postgres?sslmode=disable start, listen on 127.0.0.1:9634/metrics"
time=2026-11-01T03:55:18.046Z level=INFO msg="Listening on" address=127.0.0.1:9634

-f/--fail-fast 模式——直接失败退出,exit=2:

time=2026-11-01T03:55:16.853Z level=INFO msg="auto discovery is enabled, excludeDatabase=map[postgres:true template0:true template1:true], includeDatabase=map[]"
time=2026-11-01T03:55:16.853Z level=ERROR msg="fail creating pg_exporter: fail connecting to primary server: fail fetching server version: dial tcp 127.0.0.1:5432: connect: connection refused"

(echo $? → 2)

选型建议:exporter 与数据库同机/同编排单元(如同一 compose 栈)用默认模式,等数据库先起来(配合健康检查更佳,见部署篇 3.2 节);独立监控机用 -f,连不上就失败退出交给 systemd 的 Restart=on-failure 拉起重试,避免"假活"。

6.5 服务 active 但 pg_up 0:监控账号密码错误实录

这是 systemd 部署最隐蔽的故障——服务显示 active,但一个指标都采不上。把环境文件里的密码改成错误值并重启:

root@pgexporter-server:/tmp# systemctl restart pg_exporter && systemctl is-active pg_exporter
active
root@pgexporter-server:/tmp# curl -s localhost:9630/metrics | grep '^pg_up'
pg_up 0
root@pgexporter-server:/tmp# journalctl -u pg_exporter --no-pager -n 8 | grep -iE 'FATAL|password|error' | head -4
Nov 01 03:59:03 pgexporter-server pg_exporter[512]: time=2026-11-01T03:59:03.477Z level=ERROR msg="fail connecting to primary server: fail fetching server version: pq: password authentication failed for user \"dbuser_monitor\" (28P01) (startup will continue)"
Nov 01 03:59:07 pgexporter-server pg_exporter[512]: time=2026-11-01T03:59:07.474Z level=ERROR msg="fail scraping server [postgres]: fail fetching server version: pq: password authentication failed for user \"dbuser_monitor\" (28P01)"

诊断链条:is-active 仍是 active(因为默认 fail-fast=false,连接失败"startup will continue")→ 但 /metrics 里 pg_up 0 → journalctl 里 password authentication failed ... (28P01)(PG 密码认证错误码)。恢复正确密码后重启:

root@pgexporter-server:/tmp# systemctl restart pg_exporter && systemctl is-active pg_exporter
active
root@pgexporter-server:/tmp# curl -s localhost:9630/metrics | grep '^pg_up'
pg_up 1
pg_uptime 5025.391274

巡检规则建议:监控 pg_exporter 自身时,告警条件用 pg_up == 0 而不是服务状态——active 不等于"采得到数"。

6.6 未传 URL 的回退行为(WARN,不报错)

不传 -u 且环境变量为空时,pg_exporter 不报错而是回退默认 URL 继续启动(4.2 实例 3 的 -D 输出第一行即为该 WARN):

time=2026-11-01T03:55:20.876Z level=WARN msg="fail retrieving target url, fallback on default url: postgresql:///?sslmode=disable"

回退目标是 postgresql:///?sslmode=disable(本机 5432 + 系统默认认证),在裸服务器上若本机就有 PG 且 pg_monitor 账号配置了 .pgpass/信任认证,空参启动也能直接工作——这是 pg_exporter"单机零配置"设计;但在容器/远程场景表现为"服务起了但 pg_up 0",按 6.5 的链条查日志即可定位。另外注意 URL 未显式声明 sslmode 时 pg_exporter 会自动注入 sslmode=disable(同机优化),远程监控务必显式写 sslmode=require 级别。

七、参考链接

  1. GitHub 仓库与 Releases(v1.5.0 资产 tarball 与 checksums.txt):https://github.com/pgsty/pg_exporter/releases
  2. 官方 Docker 镜像:https://hub.docker.com/r/pgsty/pg_exporter
  3. Pigsty 官方文档:https://pigsty.io/docs/pg_exporter
  4. 站内系列篇:认知与选型见 《pg_exporter 1.5.0 介绍与选型指南》;Compose 部署与热重载实测见 《pg_exporter 1.5.0 Docker Compose 部署指南》;YAML 配置体系与采集器字段语义见 《pg_exporter 1.5.0 配置参数详解》