pg_exporter 1.5.0 配置参数详解

pg_exporter 1.5.0 YAML 配置体系逐项详解:五级探测顺序与目录合并、96 个默认采集器字段全集(ttl/timeout/版本边界/fatal/skip/tags 调度/usage 五取值/谓词查询)、官方全量配置在 PG16 的真实规划实测与三档生产配置模板。

pg_exporterPostgreSQLPrometheusGolang数据库监控2026/11/01

pg_exporter 1.5.0 配置参数详解

目标:把 pg_exporter 1.5.0 的 YAML 配置体系逐项讲透:配置文件的探测顺序与目录合并规则、96 个默认采集器的字段全集(标识/缓存/超时/版本边界/fatal/skip/tags 调度/metrics 列声明/谓词查询)、官方默认配置在 PostgreSQL 16 上的真实规划结果,以及三档可直接落地的生产配置模板。全部结论基于官方随附配置文件逐行解析与真实库实测(运行环境与实测端口见第一章),报错回显均为真实输出。

一、环境信息

本文实测环境与依据(查询/实测日期 2026-11-01):

  • 操作系统:Ubuntu 24.04 LTS(x86_64)
  • pg_exporter:1.5.0(官方镜像 pgsty/pg_exporter:1.5.0 + GitHub Release tarball 二进制 pg_exporter v1.5.0 (built with go1.27.3 on linux/amd64),--version 实测回显)
  • 被监控数据库:PostgreSQL 16.15(官方镜像 postgres:16,模拟端口 8134 → exporter 9630 的 Docker Compose 栈,部署方法见 《pg_exporter 1.5.0 Docker Compose 部署指南》)
  • 解析样本:官方随附默认配置 pg_exporter.yml(v1.5.0 Release 随附,237 KB / 约 3600 行)
  • 参照文档:官方仓库 README 与随附配置文件头部注释(config/0000-doc.yml 同源,查询日期 2026-11-01)

pg_exporter 的配置哲学是"代码里只有执行引擎,指标本体全部是配置"——本文主角的启动参数(--url/--config/--web.listen-address 等命令行 flags 与 PG_EXPORTER_* 环境变量)属于进程启动层,其逐项实测与 systemd 注入方式见 《pg_exporter 1.5.0 常用 CLI 命令与工具详解》;本文聚焦 YAML 配置文件层:每一条指标 SQL 怎么写、每个字段怎么调度。

二、前置条件

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

  1. 一个运行中的 pg_exporter:可按 《pg_exporter 1.5.0 Docker Compose 部署指南》 第四章一键拉起(含 dbtest 演示库与 demo.yml 采集器),下文实测端口 8134 即该栈的宿主端口;也可用 Release tarball 的裸二进制直接运行(--help 回显与各报错实测均来自该二进制)。
  2. 监控账号:dbuser_monitor(已授予 pg_monitor 角色),与部署篇一致,密码 q1w2e3r4。
  3. 官方默认配置文件:从 https://github.com/pgsty/pg_exporter/releases 的 v1.5.0 资产或仓库根目录获取 pg_exporter.yml(本文所有"官方默认值"统计都基于该文件逐行解析)。
  4. curl:验证指标端点与统计端点用。

三、参数查看与修改方式

pg_exporter 没有配置中心与管理界面,全部配置收敛为"一个 YAML 文件(或目录)+ 启动参数"。本章给出配置从哪来、怎么改、怎么验证生效的完整闭环。

3.1 配置文件的五级探测顺序

pg_exporter 按固定优先级定位配置文件(来源:官方随附 pg_exporter.yml 头部 "Config File" 一节原文,查询日期 2026-11-01):

  1. 命令行参数:--config=<config path>
  2. 环境变量:PG_EXPORTER_CONFIG=<config path>
  3. 当前目录:pg_exporter.yml
  4. 根配置文件:/etc/pg_exporter.yml
  5. 根配置目录:/etc/pg_exporter/

也就是说,裸跑 pg_exporter 不带任何参数时,它会依次探测 3→4→5;用 systemd(RPM/DEB 包安装)时,/etc/default/pg_exporter 里预设的 PG_EXPORTER_CONFIG=/etc/pg_exporter.yml 生效(第 2 级)。生产建议显式传 --config,让配置来源在进程日志中可追溯——启动日志会记录实际命中的级别(实测回显,来自 demo.yml 栈):

time=2026-11-01T03:32:06.822Z level=INFO msg="retrieve config path /etc/pg_exporter/demo.yml from command line"

(from command line 即第 1 级命中;若经环境变量命中,日志显示 from environment。)

3.2 单文件与目录两种形态

--config 接受两种形态(来源:官方 pg_exporter.yml 头部 "Config Format" 一节原文):

  • 单文件:一个 YAML 包含一个或多个采集器定义,每个顶层键就是一条采集器;
  • 目录:目录下所有 YAML 按文件名字母序合并为一份逻辑配置。

目录形态是官方仓库自身的维护方式:config/ 目录下 58 个采集器定义文件(0110-pg.yml、0310-pg_size.yml……)由 make conf 合并出单文件 pg_exporter.yml。生产中把"官方默认集 + 本地自定义集"分文件管理时,目录形态免维护合并顺序——字母序即加载序,自定义文件放最后(如 999-custom.yml)即可覆盖同名定义。

3.3 修改配置的三种生效途径

改完 YAML 后必须显式生效,三种途径(按推荐序):

  1. 热重载端点(推荐):curl -X POST http://<exporter>:9630/reload,零中断重规划。实测(demo.yml 追加新采集器后):

    server reloaded [HTTP 200]
    

    同时日志出现 server reloaded, 3 queries applied,新指标立即出现在 /metrics(完整实测过程见部署篇 8.2 节)。

  2. 重启进程:Docker 形态 docker compose restart exporter;systemd 形态 systemctl restart pg_exporter。适合连接串等启动参数级变更。

  3. 启动时校验:--dry-run 参数解析并打印配置后退出,用于上线前语法检查(报错形态实测见 5.7 节)。

3.4 运行时查看配置的两个端点

pg_exporter 自带两个"看配置"的 HTTP 端点(均在 9630 端口下):

  • GET /stat:查看每条采集器的执行统计(次数/缓存命中/错误/跳过/指标数/TTL/耗时)。实测回显(demo.yml 栈):

    name                     total      hit        error      skip       metric     ttl/s  duration/ms
    demo_db                  4          3          0          0          2          21     1.164441  
    demo_uptime              4          3          0          0          1          1      0.173402  
    

    列解读:total 抓取请求次数、hit 缓存命中次数(demo_db 的 TTL 30 秒内 4 次请求命中 3 次,缓存省掉了 75% 的 SQL 执行)、error/skip 计数、metric 该采集器产出的指标数、ttl/s 缓存秒数、duration/ms 最近一次执行耗时。

  • GET /explain:查看采集规划解释。实测 curl http://127.0.0.1:8134/explain 返回 HTTP 200、空正文(当前规划无待解释项时的形态);规划结论更直接的来源是启动日志的 planned with N queries, X installed, Y discarded 行(实测样例见 4.3 节)。

四、参数总览

pg_exporter 的 YAML 配置没有"全局服务段"——每个顶层键就是一条采集器定义,服务监听地址等进程级参数全部走启动参数(见 D1 篇)。本章先给全景规模,再给两张字段总表。

4.1 官方默认配置的全景规模

对 v1.5.0 随附 pg_exporter.yml 逐行解析的实测统计:

统计项实测值说明
顶层采集器定义96 个每个顶层键一条定义,与 README "96 collector branches" 口径一致
显式 name 命名空间93 条定义声明,去重 56 个README 汇报口径为 59 个 namespaces(含未显式命名的分支归组,两种统计口径并存)
metrics 列声明1176 条usage 分布:GAUGE 447 / COUNTER 488 / LABEL 194 / DISCARD 45 / HISTOGRAM 2
ttl 配置分布10s×82、60s×9、300s×3、1s×210 秒是绝对主流(README 建议的 15s 抓取间隔下的合理取值)
timeout 配置分布未设(默认 100ms)×78、2s×11、1s×7绝大多数依赖 100ms 默认超时
min_version / max_version96 个全部声明 min / 36 个声明 max版本边界是默认配置的基本盘
fatal: true3 个:pg_primary_only、pg_replica_only、pgbouncer_list与官方注释"至少设一条 fatal"的建议一致
skip: true6 个:pg_origin、pg_shmem、pg_table_bloat、pg_index_bloat、pg_tsdb_hypertable、pg_heartbeat默认关停的高成本/需额外权限采集器(pg_heartbeat 同时带谓词查询)
predicate_queries1 个:pg_heartbeat谓词查询在默认配置中的唯一实例(样例见 5.6 节)
tags 声明82 条定义带 tags前缀分布:cluster 66 / primary 10 / replica 9 / pgbouncer 12 / extension 7 / schema 3 / dbname 1

表解读:两个数字最能说明 pg_exporter 的配置形态——96 条定义全部带 min_version(版本兼容是规划的基本维度,不是可选项),82 条带 tags(绝大多数采集器都声明了自己的调度条件)。默认配置的分组编号规范(官方 "Collector Presets" 一节):1xx 基础指标、2xx 复制、3xx 持久化(大小/WAL/检查点)、4xx 活动(后端/锁/事务)、5xx 进度(vacuum/索引)、6xx 数据库级、7xx 对象级、8xx 可选(默认关闭的重查询)、9xx PgBouncer;其中 100–599 为集群级(每实例抓一次)、600–899 为库级(每库各抓)。

4.2 采集器定义字段总表

一条采集器定义可用的全部字段(字段名后为是否必填):

字段必填类型作用默认行为
<顶层键>必填键名采集器分支名,全配置唯一—
name可选字符串指标命名空间(指标前缀)缺省取顶层键名;同 namespace 多分支时规划器至多选一条
desc可选字符串采集器描述(文档作用)—
query必填SQL 块指标查询 SQL,多行块 ``
ttl可选秒结果缓存 TTL0/留空 = 不缓存
timeout可选秒查询超时,超时即取消0/留空 = 0.1(100ms);负数 = 关闭超时
min_version可选6 位整数支持的最低版本(含边界)0 = 不限
max_version可选6 位整数支持的最高版本(不含边界,[min, max))0 = 不限
fatal可选布尔该采集器失败即整个 scrape 失败,pg_up 归 0false
skip可选布尔规划阶段直接不安装(快捷关停)false
tags可选字符串数组调度标签(全集见 5.4 节)空 = 无条件安装
predicate_queries可选数组主查询前置谓词(见 5.6 节)空 = 不做前置检查
metrics必填数组返回列声明(见 5.5 节)—

💡 技术拓展:监控指标的常见类型不止 GAUGE 一种。Prometheus 指标四类型对比——

类型语义典型例子
Gauge瞬时值,可升可降连接数、数据库大小、内存占用
Counter只增不减的累计值(配合 rate() 用)查询总数、提交数、死锁次数
Histogram分桶观测分布查询耗时分布、事务年龄分布
Summary客户端侧分位数(不易聚合,Prometheus 生态较少用)Go 运行时的 GC 暂停

pg_exporter 的 usage 声明与此对应(GAUGE/COUNTER/HISTOGRAM/LABEL/DISCARD),LABEL 与 DISCARD 是导出器特有的"列角色"标注而非指标类型。默认配置的 1176 条列声明中 COUNTER(488)与 GAUGE(447)几乎对半,符合数据库监控"累计值看速率、瞬时值看水位"的混合需求。

4.3 默认配置的真实规划结果

把官方全量 pg_exporter.yml 挂到真实 PostgreSQL 16.15 上(demo 栈同款环境,监控账号 dbuser_monitor),启动日志给出的规划结果(实测回显,输出节选):

time=2026-11-01T03:42:11.165Z level=INFO msg="server [postgres] planned with 96 queries, 38 installed, 58 discarded, installed: pg_table_size, pg_primary_only, pg_timeline, pg_backup, pg_pubrel, pg_slot_16, … , discarded: pg_sub_19, pg_db_12, pg_db_10, pgbouncer_database_124, … "
time=2026-11-01T03:42:11.221Z level=INFO msg="server [dbtest] planned with 96 queries, 9 installed, 87 discarded, installed: pg_table_size, pg_pubrel, pg_relkind, pg_subrel, pg_func, pg_seq, pg_defpart, pg_table_16, pg_index , discarded: …"

/metrics 全量输出实测 1781 行(demo.yml 最小配置时为 211 行)。逐项解读:

  • 96 条定义并不会全部执行——规划器按版本边界、tags、库级别逐条裁决。postgres 主库装上 38 条(pg_slot_16 即 PG16 分支、pg_io_16 即 PG16+ 的 pg_stat_io),pg_sub_19(PG19 分支)、pg_db_10(PG10 分支)等版本不匹配的分支被丢弃,12 个 pgbouncer_* 采集器因目标不是 PgBouncer 全部不装。
  • 集群级采集器(cluster 标签)只在 postgres 库的 server 上装;库级采集器(表/索引/函数类)在 dbtest 上另装 9 条——两个库各自独立规划。
  • 这印证了 README "实际暴露的时序数量取决于 PostgreSQL 版本、启用的采集器、数据库与对象数量" 的说法:同一份 96 条配置,在不同环境装出来的指标集完全不同,且全部由配置字段自动裁决,无需人工开关。

五、核心参数分类详解

本章对每个字段给"语义 + 官方默认 + 实测样例",样例全部摘自官方默认配置或实测环境。

5.1 采集器标识:顶层键、name、desc、query

顶层键是采集器的分支名,全配置唯一;name 是指标前缀(namespace);desc 是纯文档性描述。三者关系看官方默认配置的第一条(pg_primary_only,实测摘录):

pg_primary_only:       # 顶层键 = 分支名(全配置唯一)
  name: pg             # namespace:指标前缀,本条产出 pg_uptime / pg_lsn …
  desc: PostgreSQL basic information (on primary)
  query: |-
    SELECT 
      extract(EPOCH FROM CURRENT_TIMESTAMP)                  AS timestamp,
      extract(EPOCH FROM now() - pg_postmaster_start_time()) AS uptime,
      …
      pg_is_in_recovery()                                    AS is_in_recovery,
      FALSE                                                  AS is_wal_replay_paused;
  tags: [ cluster, primary ]
  …

关键语义:

  • 指标全名 = <name>_<列名>(列未被 rename 时)。pg_primary_only 的 uptime 列最终暴露为 pg_uptime——这就是 demo.yml 里 demo_orders 命名空间的 rows 列变成 demo_orders_rows 的同一规则。
  • 同一 namespace 允许多条分支,规划器保证至多选中一条。官方配置里最典型的就是 pg 命名空间的主库/从库双分支:pg_primary_only(tags: [cluster, primary])与 pg_replica_only(tags: [cluster, replica])两条定义产出同一组指标名(pg_uptime、pg_lsn……),但 SQL 不同——主库走 pg_current_wal_lsn()、从库走 pg_last_wal_replay_lsn()。规划器按实例角色自动二选一,Grafana 大盘因此无需关心实例角色。官方注释明确:"It's the user's responsibility to make sure that AT MOST ONE collector is picked for each namespace"——同名分支的互斥条件(如 primary/replica 标签)要作者自己保证。
  • query 用 YAML 块标量(| 或 |-)承载多行 SQL,以分号结尾;列别名(AS uptime)就是后续 metrics 段的列名。

5.2 缓存与超时:ttl、timeout

这两个字段控制每条查询的执行成本,是大规模部署下防止监控拖垮数据库的两道闸门。

ttl(缓存 TTL,秒)。语义:查询结果缓存 N 秒,期间 Prometheus 重复抓取直接返回缓存(官方头部注释原文:"TTL has to be smaller than your scrape interval. 15s scrape interval and 10s TTL is a good start for production environment")。实测效果(/stat 回显,demo_db 的 TTL 为 30 秒):

name                     total      hit        error      skip       metric     ttl/s  duration/ms
demo_db                  4          3          0          0          2          21     1.164441  

4 次抓取命中 3 次缓存——真实只执行了 1 次 SQL。默认配置的取值分布(10s×82、60s×9、300s×3)体现了分层思想:高频基础指标 10 秒;体积类(pg_size)、bloat 检查类给 60–300 秒(贵查询低频跑);TTL 还被官方用来实现"不同指标不同抓取频率"——Prometheus 匀速抓取,贵查询靠长 TTL 降频。

timeout(查询超时,秒)。语义:超时立即取消查询(防雪崩);默认 0.1 秒(100ms),留空或 0 即取默认,负数关闭超时。官方头部注释同时给出警告:如果所有查询的超时加起来超过抓取/缓存间隔(通常 15s),查询仍可能积压——"or, you can just disable potential slow queries"(关掉慢查询比放大超时更健康)。默认配置中 18 条显式设了 timeout(2s×11、1s×7),全部是已知较慢的对象级统计查询;其余 78 条吃 100ms 默认值。

5.3 版本边界与开关:min_version、max_version、fatal、skip

版本边界。min_version/max_version 用 PostgreSQL 服务器版本号格式:6 位整数 <2位主版本><2位次版本><2位修订>,如 090600 = 9.6、120100 = 12.1、160000 = 16.0。区间左闭右开 [min, max),0/留空表示负无穷/正无穷(官方头部注释 "Version Compatibility" 一节原文)。版本信息来自 pg_exporter 启动时抓取的 pg_version(实测 pg_version 160015 即 16.15)。

默认配置用它实现"一条指标、多版本 SQL":如 pg_checkpointer 家族有 _10(PG10–16 的 pg_stat_bgwriter)、_17(PG17 的 pg_stat_checkpointer)、_18(PG18 新增 num_done/slru_written)三条分支,版本号自动路由。96 条定义全部声明 min_version、36 条另声明 max_version——这是动态规划的底盘。

fatal(致命采集器)。语义:标记 fatal: true 的采集器失败时,整个 scrape 立即失败、pg_up 归 0(告警触发点);非 fatal 采集器失败只累加错误计数、scrape 继续(官方头部注释 "Fatality" 一节原文,并建议"至少设一条 fatal 采集器")。默认配置恰好 3 条:pg_primary_only(主库分支)、pg_replica_only(从库分支)、pgbouncer_list(PgBouncer 场景)——基础信息查询是监控链路的生死线,挂了就该全红。

skip(直接关停)。语义:skip: true 的采集器在规划阶段就不安装(官方注释:"This could be a handy option to disable collectors")。默认配置用 skip 关停 6 条高成本或需额外权限的采集器:pg_origin(需额外权限)、pg_shmem、pg_table_bloat/pg_index_bloat(膨胀估算重查询)、pg_tsdb_hypertable(TimescaleDB 专用)、pg_heartbeat。用户侧最常用的姿势:拷贝官方配置后把不要的采集器加 skip: true(比整段删除更可追溯),或自己的新采集器开发期先 skip: true 灰度。

5.4 调度标签:tags 全集

tags 是动态规划的调度输入,决定"这条 SQL 装到哪些 server 对象上"。全集如下(来源:官方 pg_exporter.yml 头部 "Tags and Planning" 一节原文,逐类配默认配置实例):

标签语义默认配置实例
cluster集群级:同一 PostgreSQL 实例只执行一次66 条(pg_primary_only、pg_size…)
primary / master仅主库执行(pg_is_in_recovery() 为 false 时才装)10 条(pg_primary_only…)
standby / replica仅副本执行9 条(pg_replica_only…)
dbname:<名>仅指定数据库demo_orders_stat 的 dbname:dbtest;官方 pg_heartbeat 的 dbname:postgres
username:<用户>仅指定连接用户时执行—
extension:<扩展>仅装了该扩展的库执行7 条(pg_tsdb_hypertable 的 extension:timescaledb…)
schema:<模式>仅该模式存在时执行3 条
pgbouncerPgBouncer 专用采集器族12 条(pgbouncer_list…)
not:<标签>exporter 被打上 <标签> 时不执行(负标签/污点)—
<自定义标签>exporter 启动参数带了该标签(--tag)才执行—

规划时机(官方注释原文大意):pg_exporter 连上目标后先采集数据库事实(版本、角色、库清单、扩展、模式),再与每条采集器的 tags 与版本边界匹配,当且仅当完全兼容才安装。B2 部署篇 4.5 节的日志是该机制的最直观实证:

server [postgres] planned with 2 queries, 1 installed, 1 discarded, installed: demo_db_size , discarded: demo_orders_stat
server [dbtest] planned with 2 queries, 1 installed, 1 discarded, installed: demo_orders_stat , discarded: demo_db_size

demo_orders_stat(dbname:dbtest)与 demo_db_size(cluster)在同一份配置下按库自动分流。多环境单配置是 tags 的最大收益:一套配置管住主库/从库/多版本混跑机群,换环境不改配置。

5.5 列声明:metrics 与 usage 五种取值

metrics 数组逐列声明 query 返回结果的处理方式,每列可用字段:

字段必填作用
<列名>必填与 SQL 返回列名严格一致(键名即列名)
usage必填列角色,五种取值见下表
rename可选指标名别名(替代列名参与 <name>_<列名> 拼接)
description可选指标 HELP 文本
default可选列值为 NULL 时使用的默认值
scale可选值缩放因子(乘法)
bucket可选HISTOGRAM 专用的有限递增桶边界

usage 五种取值(来源:官方配置头部 "Collector Example" 注释原文):

usage语义默认配置实例
GAUGE瞬时仪表量447 条(uptime、size_bytes…)
COUNTER累计计数器(只增)488 条(xact_commit、blks_read…)
LABEL列值转为指标标签(非数值)194 条(datname、usename、state…)
HISTOGRAM每行一个观测,聚合成快照分布2 条(见下文专述)
DISCARD完全忽略该列45 条(辅助列不出指标)

HISTOGRAM 专述(v1.5.0 的特色能力,官方注释原文要点):从当前 SQL 结果重建快照分布,产出累积的 <name>_bucket{le=…}、<name>_count、<name>_sum Gauge 型序列(快照间可升可降);配合 histogram_quantile() 直接查分位数。官方默认配置的两条实例(pg_xact_age,实测摘录):

    # seconds covers every open transaction, including implicit autocommit ones in
    # flight, so _count is the current open-transaction count; low buckets absorb
    # that healthy churn.
    - seconds:      { usage: HISTOGRAM ,bucket: [1, 3, 10, 30, 100, 300, 1000, 3000, 10000, 30000, 100000] ,description: "Open transaction age snapshot in seconds" }
    # idle_seconds covers the idle-in-transaction subset; capped at 3000s (~50min)
    # since anything older is uniformly critical and lands in +Inf.
    - idle_seconds: { usage: HISTOGRAM ,bucket: [1, 3, 10, 30, 100, 300, 1000, 3000] ,description: "Idle-in-transaction age snapshot in seconds" }

官方同时给出三条使用纪律:+Inf 桶自动存在、首档有限桶隐含更低值;有符号域要显式配负数边界与 0、不要配 -Inf;禁止对快照 Histogram 序列套 rate()/irate()/increase()(它们是 Gauge 不是 Counter,权威契约见 https://exp.pgsty.com/design/snapshot-histograms/ )。

rename/default/scale 组合实例(官方 pg_io(PG16+ 的 pg_stat_io)实测摘录——毫秒转秒 + NULL 兜底):

    - read_time:          { usage: COUNTER ,default: 0  ,scale: 1e-3  ,description: "Time spent in read operations in seconds" }
    - write_time:         { usage: COUNTER ,default: 0  ,scale: 1e-3  ,description: "Time spent in write operations in seconds" }

三字段各司其职:default: 0 把 PG16 早期 pg_stat_io 的 NULL 值兜住,scale: 1e-3 把数据库返回的毫秒折算成秒——单位换算与空值治理都收敛在配置层,SQL 保持原样。

5.6 谓词查询:predicate_queries

谓词查询是主查询的前置开关:在主查询执行前(缓存命中检查之后)运行,全部返回"单行单列布尔 true"才执行主查询;任一返回 false/零行则跳过主查询(不算错误);返回多行、非布尔或报错则整条标记失败(来源:官方配置头部 "predicate queries" 注释原文)。默认配置唯一实例 pg_heartbeat(实测摘录):

pg_heartbeat:
  name: pg_heartbeat
  desc: monitoring heartbeat in monitor.heartbeat table
  predicate_queries:
    - name: if heartbeat table exists
      predicate_query: |
        SELECT EXISTS (SELECT 1 FROM information_schema.tables WHERE table_schema = 'monitor' AND table_name = 'heartbeat');
  query: |-
    SELECT id AS cluster_name, extract(EPOCH FROM ts) AS ts, lsn, txid FROM monitor.heartbeat;
  ttl: 10
  min_version: 090100
  tags: [ "dbname:postgres", "schema:monitor" ]
  skip: true
  …

解读:心跳表 monitor.heartbeat 是 Pigsty 体系的外置依赖,不是每套库都有——谓词查询先探表存在性,避免主查询直接报错刷屏;tags: ["dbname:postgres", "schema:monitor"] 再叠加库与模式两级条件。三层防线(谓词 + 库标签 + 模式标签)+ skip: true 默认关停,是"条件苛刻的可选采集器"的标准写法。适用场景:探测特定函数/表/扩展/厂商特性存在后再跑主查询(如 pg_backup_start_time() 仅 PG14+ 存在)。

5.7 配置校验与报错实录

上线前用 --dry-run 校验配置(解析并打印后退出,不连库不监听)。两种典型错误形态的实测回显(本地 v1.5.0 二进制,./pg_exporter --config=<文件> --dry-run):

错误一:非法 usage 值。错误配置(usage: FOO,五种合法值之外的任意值):

bad_usage_collector:
  name: bad
  desc: bad usage demo
  query: |
    SELECT 1 AS v;
  metrics:
    - v:
        usage: FOO
        description: wrong usage

实测回显:

time=2026-11-01T11:41:30.418+08:00 level=WARN msg="fail retrieving target url, fallback on default url: postgresql:///?sslmode=disable"
time=2026-11-01T11:41:30.418+08:00 level=INFO msg="retrieve config path e1/bad.yml from command line"
time=2026-11-01T11:41:30.418+08:00 level=ERROR msg="fail loading config e1/bad.yml, query \"bad_usage_collector\" column \"v\" has unsupported usage: FOO"

错误二:metrics 缺失/为空。错误配置(metrics: [] 空数组,另有 SQL 残缺的 query: SELECT 1 AS):

demo_broken:
  name: broken
  desc: yaml syntax error
  query: |
    SELECT 1 AS
  metrics: []

实测回显:

time=2026-11-01T11:41:30.425+08:00 level=ERROR msg="fail loading config e1/bad2.yml, query \"demo_broken\" has no metrics definition"

两条报错的解读:加载期即失败、拒绝启动(错误信息带采集器名与列名,定位直接);注意第二例——YAML 语法本身合法、SQL 残缺并不在加载期校验(SQL 只有跑起来才知道对不对),加载器检查到的是"没有可用的 metrics 定义"。另外第一例的 WARN 行顺带实证了连接串回退行为:不传 --url/PG_EXPORTER_URL 时回退默认 postgresql:///?sslmode=disable。

⚠️ 注意:配置校验只在启动与 reload 时发生。用 POST /reload 热重载一份坏配置时,重载会失败但旧配置继续生效(进程不退),修正后重新 reload 即可——这是热重载相对重启的安全优势。

六、生产配置模板

按三档场景给出可直接改造的模板。模板只示意结构与关键取值,query/metrics 的完整 SQL 从官方 pg_exporter.yml 摘取或按 5.5 节规则自写。

6.1 模板 A:官方全量 + 按需关停(推荐起步,适配 8GB+ 内存数据库服务器)。直接使用官方 pg_exporter.yml(96 采集器,PG16 上实测装出 38 条、/metrics 1781 行),把不要的重查询加 skip:

# 在官方 pg_exporter.yml 尾部追加(或直接修改对应采集器段落):
pg_table_bloat:      # 官方默认已 skip;确认保持 skip
  skip: true
pg_index_bloat:
  skip: true
# 自定义业务指标追加在最后(字母序加载,自定义放文件末尾便于维护)
demo_orders_stat:
  name: demo_orders
  desc: business table statistics
  query: |
    SELECT count(*) AS rows, coalesce(sum(amount), 0) AS amount_total FROM demo_orders;
  ttl: 5
  timeout: 1
  tags: [dbname:dbtest]
  metrics:
    - rows:         { usage: GAUGE, description: total rows }
    - amount_total: { usage: GAUGE, description: total amount }

适用:想一步到位获得 Pigsty 同款大盘指标面的团队。资源水位:exporter 进程静态单二进制(约 14.3 MB),内存占用在几十 MB 量级;数据库侧压力取决于对象数量与 TTL 设置(默认 10s 主流档)。

6.2 模板 B:最小自定义集(适配低配主机或只想监控核心水位)。不使用官方默认集,完全自写(demo.yml 即此形态,实测 211 行指标):

pg_basic:
  name: pg
  desc: minimal health set
  query: |
    SELECT extract(EPOCH FROM now() - pg_postmaster_start_time()) AS uptime,
           pg_current_wal_lsn() - '0/0' AS lsn,
           (SELECT count(*) FROM pg_stat_activity) AS active_connections;
  ttl: 5
  timeout: 1
  tags: [cluster, primary]
  fatal: true
  metrics:
    - uptime:             { usage: GAUGE, description: seconds since start }
    - lsn:                { usage: COUNTER, description: current wal write location }
    - active_connections: { usage: GAUGE, description: total connections }
pg_db_size:
  name: pg_size
  desc: per database size
  query: |
    SELECT datname, pg_database_size(datname) AS size_bytes
    FROM pg_database WHERE datallowconn AND NOT datistemplate;
  ttl: 60
  timeout: 1
  tags: [cluster]
  metrics:
    - datname:    { usage: LABEL, description: database name }
    - size_bytes: { usage: GAUGE, description: database size in bytes }

适用:边缘节点/开发库,或从零自建监控面。要点:第一条设 fatal: true 守住 pg_up 的告警语义;贵查询(size 类)TTL 拉长到 60 秒。

6.3 模板 C:目录形态的多环境单配置(适配多版本混跑机群)。目录结构:

/etc/pg_exporter/
├── 100-base.yml        # 官方默认集(从 pg_exporter.yml 拆出或整文件放入)
└── 999-custom.yml      # 自定义业务采集器 + skip 裁剪

--config=/etc/pg_exporter/ 指向目录,两文件按字母序合并;主库/从库/PG10–18 混跑机器共用同一份配置(版本边界与 tags 自动分流),每台机器的差异化(如自定义标签过滤)通过启动参数 --tag=prod 配合配置里的 <自定义标签>/not:<标签> 实现。

三档选型建议:先跑模板 A 观察 /stat 的 error 列与数据库侧负载,出现压力再降级到模板 B 或对 A 做减法;模板 C 适合机群规模上去后的配置治理形态。

七、常见问题

7.1 改了配置不生效

现象:改 YAML 后指标不变。定位:pg_exporter 不自动监听文件变化。解决:curl -X POST http://<exporter>:9630/reload(实测回显 server reloaded [HTTP 200])或重启进程;Docker 单文件挂载 + vim"重命名替换"式保存可能导致容器内文件视图断链,此时用 docker compose restart exporter(完整实测见部署篇 8.2 节)。

7.2 reload 后日志报 fail loading config,指标还是旧的

现象:POST /reload 后日志出现 5.7 节同款 fail loading config … ERROR。定位:新配置校验未通过(usage 非法/metrics 缺失/YAML 语法错)。解决:按报错定位行修正后重新 reload;坏配置不会破坏运行中的旧配置。上线前先跑 --dry-run 可提前拦截(5.7 节实录)。

7.3 某条采集器日志报错但 pg_up 还是 1

现象:日志出现单条查询 ERROR(如权限不足、函数不存在),pg_up 仍为 1。定位:该采集器未标 fatal——非致命失败只累加错误计数,scrape 整体仍成功(5.3 节语义)。解决:能修则修(授权/版本分支);确属环境不支持的采集器加 skip: true;属于生死线的基础指标才标 fatal。

7.4 指标名和列名对不上

现象:配置写 rows,指标却是 demo_orders_rows;或预期 checkpoint_write_time 实际是 pg_write_time。定位:指标全名 = <name>_<rename 或列名>——前者是 namespace 前缀规则,后者是 rename 字段生效。解决:按 5.1/5.5 节的命名规则对照;不想带前缀就把 name 设得更短(namespace 同时是多分支互斥的调度单位,改前先确认无同名分支冲突)。

7.5 同一 namespace 的多条分支全被丢弃

现象:日志 discarded 列表里同一前缀的多条分支(如 pg_db_10/12/14/18)全都没装。定位:分支互斥是"至多一条"而非"至少一条"——版本边界全不匹配(如 PG15 上 pg_db 家族的 min_version 均不覆盖 15)时全丢弃是正常行为。解决:确认目标版本号(pg_version 指标)与各分支的 [min, max) 区间;需要覆盖 15 就自写一条 min_version: 150000, max_version: 160000 的分支。

7.6 官方全量配置里找不到某个指标

现象:/metrics 里没有官方文档提到的某指标。定位:三层过滤——版本分支不匹配、tags 不满足(如 bloat 类默认 skip: true)、该指标属库级采集器而当前查看的是集群级 server 的输出。解决:用 /stat 看哪些采集器在跑、启动日志看 installed/discarded 清单(4.3 节实测方法);确认被 skip 的按需改 skip: false 并 reload。

八、参考链接

  1. 官方仓库与 README:https://github.com/pgsty/pg_exporter (Usage/Collectors 章节与 config/0000-doc.yml 文档化采集器,查询日期 2026-11-01)
  2. v1.5.0 随附默认配置:https://github.com/pgsty/pg_exporter/blob/main/pg_exporter.yml (本文全部"官方默认值"统计的解析样本;头部 1–241 行为配置格式权威注释)
  3. Snapshot Histogram 设计契约:https://exp.pgsty.com/design/snapshot-histograms/ (HISTOGRAM 使用的官方权威文档,README 引用)
  4. 站内系列篇:认知与选型见 《pg_exporter 1.5.0 介绍与选型指南》;Compose 部署与热重载实测见 《pg_exporter 1.5.0 Docker Compose 部署指南》;命令行参数与 systemd 部署见 《pg_exporter 1.5.0 常用 CLI 命令与工具详解》