把 pgBackRest 指标移出抓取路径
决策状态: 已在开发线实现;截至 2026-08-28,尚未进入
main、tag 或公开软件包。
决策日期: 2026-08-23。
适用范围: Composite Exporter 内可选的--pgbackrest缓存组件。
发布边界: 源码行为已经实现并测试;公开版本、软件包、部署和独立 exporter 退役尚未验证。
pgBackRest 通过 pgbackrest info --output=json 暴露丰富的备份状态,但它提供的是命令,不是低延迟 metrics endpoint。命令可能检查本地配置、访问远程仓库、等待存储、输出大量 JSON,或因为与 PostgreSQL SQL 指标无关的原因失败。
如果每次 Prometheus 请求都执行命令,主数据库抓取的可用性与延迟就会绑定到备份基础设施。最终设计因此把 pgBackRest 当作缓存组件:
命令路径与抓取路径不会互相等待。
有界命令执行
Collector 直接执行配置的 binary,不经过 shell。生产默认值如下:
| 控制项 | 默认值 | 契约 |
|---|---|---|
| 命令 | pgbackrest |
以固定参数直接执行 |
| 刷新间隔 | 2 分钟 | 最小 10 秒 |
| 刷新超时 | 30 秒 | 覆盖一轮后台刷新 |
| 标准输出 | 16 MiB | 硬上限;溢出立即取消命令 |
| 标准错误 | 64 KiB | 有界诊断输出 |
Worker 先检测 pgBackRest 版本,优先使用数字输出;必要时回退到旧版文本形式。随后执行 info --output=json。版本与 JSON shape 一起校验,因为不同 pgBackRest 版本的可用字段和已知兼容情况并不相同。
这些上限是安全和可靠性契约。损坏仓库、意外命令或恶意 wrapper 都不能无限分配内存,也不能在溢出后留下长期运行的子进程。Runner 在取消后还设置了很短的 wait delay,避免进程清理无限阻塞。
发布前完成全部验证
命令退出成功并不代表刷新成功。JSON 还必须满足预期文档结构、对象数量上限、数值约束、stanza 与 repository 关系,以及 metric name 和 label 规则。最终 Prometheus family 在发布前完成 normalize。
只有完整合法的 candidate 才会替换当前快照。这样 Prometheus 请求可以走更便宜的合并路径:缓存 family 已经经过完整客户端校验,每次数据库抓取只需检查所有权和 header,不再重新验证整份备份数据。
Composite 所有权顺序仍然是:
与高优先级来源冲突的 pgBackRest family 会被省略,并把组件标为 down;它不能往既有 family 添加样本,也不能让 PostgreSQL gather 变成 fatal。
Last-good 语义
至少成功刷新一次后,后续命令、超时、解析或资源上限故障会保留上一份业务 family。组件报告 up=0,增加有限错误原因,并保留最后成功时间。
这并不是“假装备份来源健康”,而是有意分开两个事实:
- 最新刷新失败;
- 如果年龄可见,上一份合法备份状态仍有价值。
相对备份年龄 Gauge 在故障期间继续增长。Worker 保存上一份合法 JSON 与版本,并可在后台只重算与当前时间相关的值。/metrics 本身永远不重新解析 JSON,也不执行 pgBackRest。
第一次成功之前没有 last-good 业务快照。健康保持 down,端点仍会返回 PostgreSQL 和其他合法组件。
健康与重叠抓取
缓存组件通过 component="pgbackrest" 进入统一健康面。除了 parse、gather 等原因,它还包含命令执行与资源上限错误。
重叠 Prometheus 请求不会排队等待完整 Composite scrape。它读取同一个原子 pgBackRest 快照,并在 family 不冲突时纳入结果。因此 overlap 期间仍可使用缓存数据,不会启动第二条命令,也不会由请求路径修改组件健康状态。
为什么不能每次抓取都执行
按需执行看似能提供更“新”的数据,却会产生多个不良契约:
- Prometheus timeout 变成备份命令 timeout;
- 并发抓取可能并发检查仓库;
- repository 延迟可能隐藏 PostgreSQL 指标;
- scrape storm 会放大本地与远程存储负载;
- 命令输出大小与进程清理变成 HTTP handler 职责。
独立 exporter 进程提供更强的进程隔离,但会保留额外端口、target、软件包和健康模型。Composite 模式提供迁移选择,并不声称所有环境必须立即退役独立进程。
通用命令 plugin framework 同样被拒绝。pgBackRest 的 JSON、版本兼容、安全、指标与 last-good 语义都具有领域特性。把它当任意 shell 输出会削弱验证,并让尚未稳定的 plugin API 进入产品表面。
运维结果
启用组件意味着 PG Exporter service 获得执行 pgBackRest 和读取其配置的权限。官方 PG Exporter 软件包无需捆绑 pgBackRest binary;可执行文件与 repository credential 继续由主机备份安装负责。
运维人员必须对组件健康和最后成功年龄告警,不能只看备份指标仍然存在。替换独立 exporter 前,还必须用最终软件包和真实 service user 验证实际仓库。源码测试、tag、打包、Pigsty target 修改与生产等价性是独立验收门槛。
外层协调器与失败规则见一个端点,多种来源。