# SQL 可观测基线

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

---

数据库“忙”只是结果，SQL workload 才是来源之一。

要回答：

```text
哪类语句消耗了时间？
调用量还是单次成本改变？
时间花在执行、计划、I/O、JIT、WAL 还是临时块？
慢是一直慢，还是 tail 中少量异常？
统计从什么时候开始？
query identity 是否稳定？
日志和计划采集付出了多少额外成本？
证据是否泄露业务值？
```

需要组合三个接口：

```text
pg_stat_statements
  聚合 workload population

bounded logging
  离散慢语句、错误、锁等待、临时文件

auto_explain
  对满足政策的一部分执行自动记录计划
```

三者都有盲区，也都有成本。最危险的做法是为了“可观测”无界记录所有 SQL 和
参数，结果既拖慢系统，又制造一份高密度敏感数据库。

## 25.3.1 `pg_stat_statements` 的统计口径与重置 {#item-25-3-1}

### 它不是默认自动完整可用

`pg_stat_statements` 需要：

1. 出现在 `shared_preload_libraries`；
2. PostgreSQL 重启后模块被加载；
3. 每个需要查询视图的 database 安装 extension；
4. query identifier 可用；
5. 查询角色有足够权限；
6. 容量、track policy 和 reset 被声明。

检查：

```sql
SELECT name, setting, source
FROM pg_settings
WHERE name IN (
  'shared_preload_libraries',
  'compute_query_id',
  'pg_stat_statements.max',
  'pg_stat_statements.track',
  'pg_stat_statements.track_utility',
  'pg_stat_statements.track_planning',
  'pg_stat_statements.save'
)
ORDER BY name;
```

extension 可能不在 `public`：

```sql
SELECT
  e.extname,
  e.extversion,
  n.nspname AS extension_schema
FROM pg_extension AS e
JOIN pg_namespace AS n ON n.oid = e.extnamespace
WHERE e.extname = 'pg_stat_statements';
```

Pigsty 沙箱中的结果：

```text
shared_preload_libraries        pg_stat_statements, auto_explain
compute_query_id                auto
pg_stat_statements.max          10000
pg_stat_statements.track        all
pg_stat_statements.track_utility off
pg_stat_statements.track_planning off
pg_stat_statements.save         on
extension version              1.12
extension schema               monitor
```

所以查询使用：

```sql
monitor.pg_stat_statements
monitor.pg_stat_statements_info
```

不要硬编码成 `public.pg_stat_statements`。

### 聚合键不是 query text

一行主要按以下身份聚合：

```text
dbid
userid
queryid
toplevel
```

这意味着：

- 同一 queryid 在不同 database 分开；
- 不同执行角色分开；
- top-level 与 nested statement 分开；
- query text 是一个代表性 normalized text，不是主键；
- 同一可见文本仍可能因语义环境不同获得不同 queryid；
- hash collision 在理论和实践上都可能发生。

因此关联时保留：

```text
cluster / instance
dbid
userid or role class
queryid
toplevel
stats_since
```

只保存 queryid 而丢掉 database/user/toplevel，会把不同 workload 合并。

### normalization 不是脱敏承诺

常量通常会被替换：

```sql
SELECT * FROM orders WHERE order_id = 123;

-- representative normalized form
SELECT * FROM orders WHERE order_id = $1;
```

但不能据此认为 `query` 列可以公开：

- object 名可能包含客户或项目身份；
- comment 可能含敏感上下文；
- dynamic SQL 结构可能暴露值；
- utility statement 的行为不同；
- query text 与日志/错误组合可能重新识别业务；
- 权限边界本身说明它被视为敏感。

本章 evidence 明确：

```text
query text exported   false
bind values exported  false
client address        false
```

### queryid 是关联键，不是密码学身份

queryid 是内部 hash：

- 算法可能随 major version 改变；
- collision 可能发生；
- object identity 与 `search_path` 会影响语义；
- 相同显示文本可能代表不同解析对象；
- failover/upgrade 前后要重新建立 baseline。

不要用 queryid：

- 做访问控制；
- 证明 SQL 完全相同；
- 做永久跨版本业务 ID；
- 取代 plan fingerprint；
- 取代 application operation class。

它适合：

- workload 聚合；
- before/after 比较；
- dashboard 下钻；
- 与受限日志/plan 关联；
- top-N 诊断。

### 从总时间拆成频率与单次成本

$$
\text{total execution time}
=
\text{calls}
\times
\text{mean execution time}
$$

top total time 可能来自：

```text
very frequent cheap query
rare extremely slow query
both
```

基本查询不要一开始读 text：

```sql
SELECT
  dbid,
  userid,
  queryid,
  toplevel,
  calls,
  round(total_exec_time::numeric, 2) AS total_exec_ms,
  round(mean_exec_time::numeric, 3) AS mean_exec_ms,
  round(min_exec_time::numeric, 3) AS min_exec_ms,
  round(max_exec_time::numeric, 3) AS max_exec_ms,
  rows,
  shared_blks_hit,
  shared_blks_read,
  temp_blks_written,
  wal_bytes,
  stats_since,
  minmax_stats_since
FROM monitor.pg_stat_statements
ORDER BY total_exec_time DESC
LIMIT 50;
```

注意：

- min/max 易受单次异常影响；
- mean 掩盖分布；
- row count 的语义随 statement 类型变化；
- block 是 PostgreSQL block，不是任意存储 byte；
- I/O timing 依赖开关；
- WAL byte 不等于 commit durability；
- top-N 会漏掉排名外 workload。

### 用 delta，而不是跨 reset 比裸值

两个采样点：

```text
t0: calls_0, total_exec_0, stats_since_0
t1: calls_1, total_exec_1, stats_since_1
```

只有 identity 与统计窗口连续时才计算：

$$
\Delta calls = calls_1 - calls_0
$$

$$
\text{window mean}
=
\frac{\Delta total\_exec\_time}
{\Delta calls}
$$

如果：

- row 消失；
- `stats_since` 改变；
- postmaster restart；
- extension reset；
- entry deallocated 后重新创建；
- failover 到另一成员；

就不能直接减。

### `pg_stat_statements_info` 是解释入口

```sql
SELECT *
FROM monitor.pg_stat_statements_info;
```

核心：

```text
dealloc
stats_reset
```

`dealloc` 增长表示 statement entry 因容量压力被丢弃。此时 top workload 可能
被 churn 影响；应评估：

- `pg_stat_statements.max`；
- query shape 数量；
- dynamic SQL；
- reset；
- 内存成本；
- 是否需要更稳定的 application query pattern。

沙箱正式快照：

```text
dealloc              0
stats_reset          2026-07-29T18:57:02Z
statement rows       194
calls                超过 100,000
```

这是一次窗口基线，不是永久容量结论。

### 每行还有自己的时间边界

PostgreSQL 18 的 statement 行包含：

```text
stats_since
minmax_stats_since
```

如果只 reset 某条或只 reset min/max，不同 entry 的窗口可能不同。一个 dashboard
不能只在标题写全局“过去 24 小时”，却忽略每行实际开始时间。

### reset 是破坏性观察动作

函数可以全局或选择性 reset；当前版本还支持只 reset min/max。它很有用，但
会销毁比较基线。

原则：

```text
incident capture
  never reset to make the graph easier

planned benchmark
  may reset in an isolated target with explicit evidence

production baseline
  prefer snapshots/deltas and recording rules
```

本章 L0 采集明确禁止：

```text
pg_stat_statements_reset
pg_stat_reset*
```

如果必须 reset：

- 记录 request/approval；
- exact target；
- old reset time；
- snapshot/hash；
- reason；
- expected observation gap；
- downstream dashboard impact；
- new baseline start。

### planning 与 execution 并非一一对应

`pg_stat_statements.track_planning=on` 可以收集 plan count/time，但：

- 默认通常为 off；
- 对高并发相同 query，plan 统计更新会有明显开销；
- prepared/cached plan 改变 plan/execute 次数关系；
- 执行失败与计划失败的记录条件不同；
- utility 和 nested track policy 影响 population。

沙箱 `track_planning=off`，所以：

```text
total_plan_time = 0
```

表示未收集，而不是规划不耗时。不要为了填满 dashboard 直接在生产开启；先做
负载测试和决策评审。

### `track=all` 的语义

`top` 只跟踪 top-level；`all` 还跟踪 nested statement。沙箱设置 `all`，再用
`toplevel` 区分。否则 stored procedure 或 function 内 SQL 可能看不见，或被
误与 top-level 混合。

### top-N 查询要保护系统

观察查询也消耗：

- shared memory lock；
- sort；
- format/round；
- dashboard 并发；
- network；
- 结果存储。

生产查询建议：

```sql
SET LOCAL statement_timeout = '5s';
SET LOCAL lock_timeout = '500ms';

-- 只读、限制列、限制行、先 aggregate identity
```

不要每 5 秒在每个 database：

```sql
SELECT * FROM pg_stat_statements ORDER BY total_exec_time DESC;
```

尤其不要自动导出完整 query text。

### 建立 workload baseline

基线至少分：

```text
calls rate
total/mean/max execution
rows per call
shared hit/read/write
temp blocks
WAL bytes
JIT time/count
planning if explicitly enabled
stats reset / entry age
```

按：

```text
service operation
database
role class
queryid
release/change window
```

关联。不要仅按 instance；failover 后 workload 会移动。

## 25.3.2 慢语句、锁等待、临时文件与错误日志 {#item-25-3-2}

### 慢日志是离散样本

核心设置：

```sql
SELECT name, setting, unit, source
FROM pg_settings
WHERE name IN (
  'log_min_duration_statement',
  'log_min_duration_sample',
  'log_statement_sample_rate',
  'log_duration',
  'log_statement',
  'log_lock_waits',
  'deadlock_timeout',
  'log_temp_files',
  'log_min_error_statement',
  'log_parameter_max_length',
  'log_parameter_max_length_on_error'
)
ORDER BY name;
```

### `log_min_duration_statement`

记录执行时间达到阈值的语句；`0` 表示记录全部，`-1` 关闭。

优点：

- 对超过阈值的 population 较完整；
- 可以看到离散 tail；
- 能与 queryid、错误和时间线关联。

代价：

- I/O 与格式化；
- log volume；
- SQL/参数泄露；
- 高频略慢语句形成洪水；
- 日志系统成为新瓶颈。

### `log_min_duration_sample`

达到 sample threshold 后，再按 `log_statement_sample_rate` 采样。它适合控制
高流量环境的日志量，但“未出现”不能解释为“未发生”。

如果：

```text
log_min_duration_sample = -1
log_statement_sample_rate = 1
```

采样路径仍是关闭的。不要只看 rate。

### duration 的边界

语句 duration 与用户 end-to-end latency 不同。用户时间可能包括：

```text
network
application queue
pool wait
server execution
result transfer
application processing
retry
commit reconciliation
```

PostgreSQL 慢日志只覆盖 server 侧语句范围。

### lock wait 日志

`log_lock_waits=on` 在等待超过 `deadlock_timeout` 时记录。沙箱：

```text
log_lock_waits   on
deadlock_timeout 50ms
```

这意味着：

- 超过约 50 ms 的 lock wait 有机会被记录；
- 更短等待可能很多但没有日志；
- deadlock detection cadence 与日志量相关；
- 不能为了更多日志随意降低 timeout；
- 日志是离散事件，当前 lock view 是即时状态。

调查组合：

```text
user latency window
pg_stat_activity current wait
pg_locks / pg_blocking_pids
lock wait logs
deadlock counter
application transaction boundary
```

### temporary file

`log_temp_files` 在临时文件删除时记录超过阈值的文件。沙箱为：

```text
1024 kB
```

这类日志说明：

- 某操作产生了 temp file；
- 大小达到记录政策；
- 日志时刻可能是删除时刻，不是创建/峰值时刻。

关联：

- `pg_stat_database.temp_files/temp_bytes`；
- `pg_stat_statements.temp_blks_read/written`；
- queryid；
- plan；
- sort/hash/window；
- workload concurrency；
- `work_mem` policy。

不要看到 temp 就全局提高 `work_mem`。它按 operation/node/worker 使用，高并发
会把一个小改动放大成内存风险。

### error log 与用户 outcome

PostgreSQL error 包含 SQLSTATE、severity、detail、context 等；应用可能：

- retry 后成功；
- 返回失败；
- 超时但 commit；
- 屏蔽错误；
- 将一个 DB error 映射成不同业务 outcome。

所以错误日志要与应用 outcome 关联，而不是用 log line 数直接做 availability
分子。

稳定聚合维度：

```text
cluster / instance / database
severity / SQLSTATE class
application / operation class
release
```

不适合作 label：

```text
full message
detail
statement
parameter
customer/order/tenant
```

### structured CSV/JSON 不会自动安全

沙箱使用：

```text
logging_collector on
log_destination csvlog
log_directory /pg/log/postgres
log_filename postgresql-%a.log
```

CSV 方便 Vector 解析，但：

- statement 字段仍可能敏感；
- detail/context 可能含值；
- file permission/collector group 需要评审；
- 集中存储扩大读取面；
- retention 必须独立设置。

### 从 metric 到 log，而不是无界 log query

正确流程：

```text
metric identifies:
  service, environment, operation, time window

event identifies:
  release/change boundary

log query:
  bounded window + stable fields + maximum rows

result:
  aggregate error classes, do not export bodies
```

本章诊断包规定：

```text
log query limit  1000
body export      forbidden
```

需要正文时，应在受限界面临时查看并按事件政策处理，而不是复制进公共工单。

### 日志缺失也有语义

没有日志可能是：

- 事件未发生；
- threshold 未达到；
- sampling 丢失；
- collector/Vector 失败；
- rotation/retention；
- parse schema drift；
- 权限或查询错误；
- 日志写入阻塞；
- service 在另一 instance。

必须同时观察 log pipeline。

## 25.3.3 `auto_explain` 的采样、嵌套语句与开销 {#item-25-3-3}

### `auto_explain` 解决什么

`pg_stat_statements` 告诉你：

```text
which queryid is costly
```

`EXPLAIN`/`EXPLAIN ANALYZE` 告诉你：

```text
how one plan is structured and executed
```

`auto_explain` 在满足政策时自动把 plan 写入日志，适合捕捉难以手工复现的慢
执行。

它不是零成本“打开即可”。

### 最重要的开关

```sql
SELECT name, setting, unit, source
FROM pg_settings
WHERE name LIKE 'auto_explain.%'
ORDER BY name;
```

| 设置 | 问题 |
|---|---|
| `log_min_duration` | 多慢才记录；默认 `-1` 不启用 |
| `sample_rate` | 满足阈值的 statement 采样多少 |
| `log_analyze` | 是否实际执行统计进入 plan |
| `log_timing` | `ANALYZE` 时是否逐节点计时 |
| `log_buffers` | 是否记录 buffer 使用 |
| `log_wal` | 是否记录 WAL 使用 |
| `log_nested_statements` | function 内语句是否记录 |
| `log_parameter_max_length` | 参数记录长度 |
| `log_format` | text/xml/json/yaml |
| `log_verbose` | 是否输出额外细节 |
| `log_settings` | 是否记录影响 planning 的设置 |
| `log_triggers` | trigger 统计 |

### `log_analyze` 的隐藏成本

官方文档特别警告：启用 `log_analyze` 后，即使最终语句没有达到
`log_min_duration` 而不写日志，也可能需要为所有语句做 per-plan-node timing。

如果同时：

```text
log_analyze=on
log_timing=on
sample_rate=1
```

开销可能非常高，尤其是大量短 node 的 workload。

`log_timing=off` 可以保留 rows 等实际统计并减少逐节点时钟调用，但仍需实测。

### 沙箱的真实设置

本章只读检查发现：

```text
auto_explain.log_min_duration       1000 ms
auto_explain.log_analyze            on
auto_explain.log_timing             on
auto_explain.log_nested_statements  on
auto_explain.sample_rate            1
auto_explain.log_parameter_max_length -1
```

这不是推荐模板。它是一个需要单独 overhead 与泄露评审的真实基线：

- `sample_rate=1` 没有限制 eligible statement；
- `log_analyze + log_timing` 有全局计时成本；
- nested 可能显著放大日志量；
- parameter length `-1` 允许完整参数；
- 阈值 1 秒只限制最终写 plan，不一定消除 instrumentation cost。

本章不 reload、不改参数，只把风险记录下来。

### `BUFFERS` 与 `WAL` 依赖 `ANALYZE`

自动计划中的实际 buffer/WAL 信息要求 analyze path。不能关闭 analyze 后仍假装
获得运行时资源。

设计取舍：

```text
plan shape only
  lower runtime detail, lower cost

analyze without timing
  actual rows/buffer possibility, less per-node clock cost

analyze with timing
  richer node time, potentially high overhead
```

必须在代表性 workload 上量化。

### nested statement

function、trigger、procedure 内可能包含真正慢的 SQL：

```text
top-level CALL
  cheap wrapper
  nested SQL expensive
```

`log_nested_statements=on` 能看见，但会：

- 增加 volume；
- 重复上下文；
- 暴露更多 query/parameter；
- 让一个 top-level 请求产生多份 plan。

同时使用 `pg_stat_statements.track=all` 与 `toplevel` 关联。

### 采样测试应覆盖 tail

开启前在隔离 workload 回答：

```text
baseline TPS / p50 / p99
CPU and system time
log bytes per second
collector lag
plan count
short statement overhead
long statement capture probability
nested amplification
parameter redaction
rollback path
```

不要只跑一条慢查询说“开销不大”。

### 不要在事故中临时全开

事故中：

```text
log_min_duration=0
log_analyze=on
log_timing=on
sample_rate=1
```

可能：

- 进一步降低吞吐；
- 加剧 disk/log pipeline；
- 泄露参数；
- 改变被观察 workload；
- 制造新的故障。

更安全顺序：

1. 用现有 SLI、activity、wait、queryid 缩小范围；
2. 使用已有日志与 plan；
3. 评估只对 session/role/database 的受控方法；
4. 明确 timeout、采样、持续时间和 rollback；
5. 由变更政策批准；
6. 观察 overhead；
7. 到期自动撤销并验证。

### `auto_explain` 不是 plan history 系统

计划只在满足政策时进入日志；sampling、rotation、retention、parse 都会造成
缺口。若要做 plan regression：

- 在测试/发布流程保存 `EXPLAIN (FORMAT JSON)`；
- 记录 schema/statistics/version/settings；
- 与 queryid/plan fingerprint 关联；
- 不要把生产日志当完整 plan catalog；
- 不要在没有参数与数据分布语义时做机械 diff。

## 25.3.4 日志不得泄漏密码、令牌和敏感参数 {#item-25-3-4}

### SQL observability 是高敏感数据面

可能出现：

```text
password in connection/DDL statement
API token in INSERT/UPDATE
tenant/customer/order identity
email/phone/address
medical/payment attributes
session variable
RLS predicate context
error detail containing row values
dynamic SQL comment
connection URI
```

PostgreSQL 文档明确警告，statement logging 可能暴露敏感数据，甚至明文密码。

### 参数记录的两套限制

```text
log_parameter_max_length
  非错误 statement 的参数记录限制

log_parameter_max_length_on_error
  错误发生时的参数记录限制
```

一般语义：

```text
0    disable
-1   no length limit
N    truncate to N bytes
```

`auto_explain.log_parameter_max_length` 又是独立设置。

沙箱：

```text
log_parameter_max_length           -1
log_parameter_max_length_on_error   0
auto_explain.log_parameter_max_length -1
```

这表示错误路径参数被禁用，但普通慢 statement/auto_explain 仍可能完整记录参数。
是否安全取决于 protocol、query 和应用，不能因为“一项为 0”宣布无泄露。

### `log_statement` 的风险

`log_statement=all` 会记录每条 statement；DDL 中尤其可能出现：

```sql
CREATE ROLE app LOGIN PASSWORD '...';
ALTER ROLE app PASSWORD '...';
```

即使参数化 DML 避免 literal，DDL、utility、comment 和 dynamic SQL 仍可能带
秘密。生产不得把“排障方便”当默认充分理由。

### 文件模式：0600 不是唯一安全答案

PostgreSQL `log_file_mode` 控制 collector 创建文件的 mode。

```text
0600
  PostgreSQL OS owner only

0640
  owner read/write + restricted collector group read
```

Pigsty 使用 Vector 收集日志时，受控 group read 可能是合理实现。安全要求是：

```text
not world-readable
collector group explicitly declared
membership minimal
no interactive user by default
directory traversal restricted
rotation preserves mode
central storage ACL reviewed
```

沙箱为 `0640`。本章没有证明 collector group membership 已完成生产审批，因此
将其作为待评审事实，而不是自动判定安全或不安全。

### 传输到 VictoriaLogs 扩大了边界

原本只有 database host 上的日志，集中后可能被：

- Grafana data source；
- log query API；
- incident automation；
- backup/export；
- 多个 operator

访问。

必须重新定义：

```text
ingestion TLS/auth
tenant isolation
query role
retention
deletion
export
redaction
audit
backup
```

“源文件权限正确”不能证明集中日志安全。

### metric label、alert annotation、ticket 是二次泄露面

最常见事故不是直接开放 log file，而是自动化复制：

```text
log body
  -> alert annotation
      -> chat webhook
          -> ticket
              -> email
                  -> postmortem
```

本章诊断包只导出：

- error class/count；
- queryid；
- database/role class；
- time window；
- release/change id；
- source link without credentials。

不导出：

- statement；
- bind value；
- log body；
- client address；
- tenant/order/customer。

### redaction 要在尽量靠近 source 的位置

优先级：

1. 应用不把 secret 放进 SQL/comment；
2. 参数化查询；
3. PostgreSQL logging policy 限制；
4. collector parse/redact；
5. storage ACL/retention；
6. alert/evidence allowlist。

最后一步 regex 不是万能防线：

- 数据格式会变化；
- 编码/截断会绕过；
- 新字段未被匹配；
- secret 可能已进入上游缓存/备份。

### query text 的受控交互查看

真正排障有时需要 SQL text。正确做法不是绝对禁止人看，而是区分：

```text
machine evidence
  no query text

interactive diagnosis
  time-bounded pg_read_all_stats or narrower role
  approved operator
  restricted UI/session
  no casual copy
  audit and expiry

public/reference summary
  queryid and aggregates only
```

这既保留诊断能力，也控制扩散。

### prepared statement 不自动消除泄露

参数化可以让 statement text 不含 literal，但：

- bind parameter logging 仍可能记录值；
- 错误 detail/context 可能包含；
- 应用 comment/baggage 可能包含；
- object/table/schema 名仍可能敏感；
- auto_explain parameter logging 是独立开关。

所以要检查完整链路，不只看应用 ORM。

### 慢日志与审计日志不是一回事

慢日志回答 performance sample；审计回答谁在何时对什么对象做了什么。两者：

- 目的不同；
- 保留不同；
- 访问不同；
- 完整性要求不同；
- 敏感性不同。

不要让 `log_statement=all` 同时冒充性能、审计、合规和安全检测。需要审计时，
使用明确的审计政策、对象范围和审阅流程。

### 安全基线查询

```sql
SELECT name, setting, source
FROM pg_settings
WHERE name IN (
  'logging_collector',
  'log_destination',
  'log_directory',
  'log_filename',
  'log_file_mode',
  'log_statement',
  'log_min_duration_statement',
  'log_min_duration_sample',
  'log_statement_sample_rate',
  'log_parameter_max_length',
  'log_parameter_max_length_on_error'
)
OR name LIKE 'auto_explain.%'
ORDER BY name;
```

这只是配置事实，还要复核：

- actual file mode/owner/group；
- directory mode；
- Vector identity/config；
- VictoriaLogs access/retention；
- sample log 是否被正确 parse/redact；
- alert/template 是否复制 body；
- backup 是否包含日志。

本章 L0 只记录配置，不读取日志正文。

### SQL 可观测基线清单

```text
extension
  preload / version / schema / query id

population
  track / utility / nested / max

time
  global reset / per-row stats_since / minmax_stats_since

cost
  planning / timing / auto_explain / logging volume

security
  query visibility / parameters / file group / central log ACL

diagnosis
  calls / exec / rows / blocks / temp / WAL

correlation
  service / operation / release / database / role / queryid

boundary
  no query text in automatic evidence
```

### 本节验收

你应当能够解释：

1. 为什么 extension schema 不能假设是 `public`；
2. 一行 `pg_stat_statements` 的四个核心聚合维度；
3. normalization 为什么不是脱敏保证；
4. queryid 为什么不能做永久或安全身份；
5. `calls`、total、mean、max 各说明什么；
6. `dealloc`、global reset、`stats_since`、`minmax_stats_since` 的差异；
7. `track_planning=off` 时 plan time 为零意味着什么；
8. 慢语句、采样慢语句、lock wait 和 temp file 日志各何时产生；
9. `auto_explain.log_analyze + log_timing` 为什么可能给所有语句带来成本；
10. nested statement 为什么同时增加诊断价值与泄露/volume；
11. `0640` 如何在受控 collector group 下成立；
12. 为什么自动 evidence 只保留 queryid 与聚合，而交互查看另行授权。

---

[上一节：PostgreSQL 核心运行信号](../02/) · [返回本章目录](../) · [下一节：把观察契约变成告警](../04/) ·
[查看全书目录](/toc/) · [查看索引中心](/indexes/)
