# 目标身份与一致的健康检查响应

LLMS 索引： [llms.txt](/zh/llms.txt)

---

> **状态：** 已随 v1.5.0 发布。<br>
> **决策与最后核验日期：** 2026-10-23。<br>
> **范围：** v1.5.0，源码 `1891254`（修复基线 `9b378cb`），涵盖连接串与数据库身份、由元数据驱动的采集器选择、HTTP 健康状态快照、YAML 时间配置及指标路由校验。<br>
> **交付：** 源码已提交并推送，v1.5.0 标签指向 `18912540fe5edce0ed0ee81fac0d989738ecaa87`；CI 与正式发布工作流通过，GitHub Release、RPM／DEB／压缩包和 Docker 镜像已发布。未据此声称生产部署或生产负载验收完成。

## 目标身份

URL 语法或查询参数转义错误必须阻止启动，且不能打印原始连接串或含有连接串的解析错误。共享 URL 解析器还须拒绝解码后为空、包含 Unicode 空白或 `=` 的查询参数名，防止这些名称进入驱动解析或绕过密码遮盖。诊断使用固定文本，不包含连接串或错误参数名。静默丢弃错误参数可能连显式 TLS 设置一起丢掉。省略 `sslmode` 时仍默认使用 `disable`；有效的显式设置保持不变。

所支持 URL 形式中的数据库名交给现有 `lib/pq` 解析器确定，涵盖路径、显式查询参数和数据库别名。Exporter 自行模拟它们的优先级容易把 PgBouncer 当成 PostgreSQL，或错误识别自动发现的数据库。发现新库后，替换连接串时移除 `dbname`、`database` 两个查询参数，将库名写入唯一且正确转义的路径，保留其他参数及库名的原始字符。Service 文件中的目标解析，以及仅依赖连接默认值推导的 PgBouncer 身份，不在本次修复范围内。

选用 `PG_EXPORTER_URL_FILE` 时，文件内容为空或仅含空白必须阻止启动。此处检查的是保存连接 URL 的文件，不是 TLS 私钥文件。

## 采集器选择

元数据预检成功后，用户名、Schema 集合或扩展集合变化也应使查询计划失效，沿用版本、数据库名和恢复状态变化时的处理方式。比较集合而非返回数组顺序。下一轮采集通过既有计划流程重新选择采集器、重建缓存并重置查询统计；元数据不变则保留现有计划和缓存。安装扩展后不再需要手工重载，也不增加后台线程或额外元数据查询。

## 健康状态快照

只发布一个原子状态枚举：unknown、down、starting、primary、replica。`Up()` 和 `Recovery()` 从这个值推导。每个健康检查 HTTP 请求只读取一次，并同时推导状态码和响应正文。三个分别原子更新的字段并不是一份原子快照；重复读取也可能混合不同探测轮次的状态。

沿用既有路由、HTTP 状态码、后台探测间隔和采集结果更新健康状态的方式。此决定保证单次响应内部一致，并不把缓存状态变成数据库实时可用性的同步证明。完整状态可存入一个原子整数，无需增加互斥锁。

## 指标路由

启动校验必须确认对配置路径的请求选中了指标处理器本身。仅比较匹配的路由字符串并不充分：mux 的重定向也可能返回相同字符串，却没有进入指标处理器。校验时比较返回的处理器与注册的指标处理器，拒绝落入重定向或其他端点的路径，保留在当前 mux 下确实可达的转义路径，无须一概禁止百分号转义。

## 验证与边界

回归测试覆盖显式数据库身份、特殊字符和冲突参数、错误 URL、Schema／扩展／用户资格变化、元数据顺序不变、并发健康状态切换，以及两种 HTTP mux 下的可达转义路径和重定向。新增用例在修复前失败、修复后通过。

v1.5.0 发布前验收补充了以下验证：

- 错误的 TLS 转义在连接前被拒绝；`verify-full` 对不提供 TLS 的服务器连接失败。日志不包含连接密码，空 URL 文件被拒绝。
- 含冲突参数和特殊字符的自动发现连接返回正确数据库指标；增加与删除数据库、Schema、`hstore` 后，采集计划按元数据更新。稳定集合保留缓存。
- 非法单文件重载保留旧定义和缓存；断连后健康检查恢复；物理备库晋升后角色与标签选择更新；并发抓取、健康与重载请求的状态码和正文保持一致。
- Go race 测试、两种 HTTP mux、`go vet`、Staticcheck、模块与生成配置一致性、六平台构建、RPM／DEB 安装和 Docker 构建通过。针对有效 UTF-8 URL 身份及实际 HTTP URL 构造的短时模糊测试完成约 60.4 万次输入。
- 以非超级用户重新验证 PostgreSQL 9.1–9.6、10–18、19 RC1 的默认主库采集，以及 PgBouncer 1.26.1。PG10–13 使用已记录的订阅 OID 授权。此范围不代表穷尽扩展、瞬态故障和生产负载。

证书链／主机名／双向 TLS 的全部组合、SQLSTATE `57P03` 的真实启动瞬态和生产负载不在本轮完整验证范围内。Docker 的证书验证仍需按手册挂载 CA。目录加载可跳过错误文件；空 YAML 是合法的零采集器配置；`SIGTERM` 不等待活跃 HTTP 请求。上述既有行为没有改变。

配套配置校验在转换为 `time.Duration` 前拒绝 YAML 主查询 TTL、查询 timeout 和谓词 TTL 中非有限或正向溢出的秒数，保留零值、默认值及有限负超时的既有语义。本次不迁移驱动，不整合可选组件，不修改指标名称，也不做通用重构。
