Skip to content

Commit 63f0c5b

Browse files
author
xiongcc
committed
添加第6章: How to work with pg_stat_statements, part 2
1 parent 3eabc7a commit 63f0c5b

File tree

1 file changed

+37
-0
lines changed

1 file changed

+37
-0
lines changed
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
# How to work with pg_stat_statements, part 2
2+
3+
昨天我们讨论了使用 pg_stat_statements (pgss) 的一些基础知识,以及第一组衍生指标 `dM/dt`——基于时间的微分。今天我们将重点关注第二组指标:`dM/dc`,其中 c 表示调用次数 (pgss 中的 `calls` 列)。
4+
5+
## 衍生指标2. 基于调用次数的微分
6+
7+
这一组指标的重要性不亚于基于时间的微分,因为它可以为你提供工作负载的系统化视图,是查询性能宏观优化的有力工具。
8+
9+
这组指标帮助我们理解每个查询组的平均查询特性。
10+
11+
不幸的是,许多监控系统忽视了这种衍生指标。一套好的系统应该展示全部或至少大部分此类指标,并显示这些值随时间变化的图表 (`dM/dc` 时间序列)。
12+
13+
获取此类衍生指标的结果非常简单:
14+
15+
- 计算两个 pgss 快照之间的 M 值 (正在研究的指标) 的差值:`M2 - M1`
16+
- 然后,不使用时间戳,而是获取 "calls" 值的差值:`c2 - c1`
17+
- 接着计算 `(M2 - M1) / (c2 - c1)`
18+
19+
让我们看看通过这种方式获得的各种衍生指标的意义:
20+
21+
- `dM/dc`,当 `M``calls` 时 — 这是一种退化情形,该值始终为1 (调用次数除以相同的调用次数)。
22+
- `dM/dc`,当 `M` 是 `total_plan_time + total_exec_time` 时 — 这是某个特定 pgss 查询组中查询的平均执行时间,这是查询性能观察中的一个极其重要的指标。它也可以称为 "查询延迟"。当应用于 pgss 中所有标准化查询的聚合值时,其意义是 "服务器上平均查询延迟" (有两个重要的注意事项:pgss 并不追踪失败的查询,并且由于 `pg_stat_statements.max` 限制,有时数据可能偏斜)。Postgres 的主要累积统计信息系统并不提供这种信息 — `pg_stat_database` 仅在 `track_io_timing` 启用时才会跟踪一些时间指标,如 `blk_read_time` 和 `blk_write_time`,在 PG14+ 中还有 `active_time`,但它不包含语句数量的信息,只记录事务数量 (`xact_commit` 和 `xact_rollback`);在某些情况下,我们可以从其他来源获得这些数据 — 例如,pgbench 在用于基准测试时会报告这些数据,pgBouncer 也会报告事务和查询的平均延迟,但在常规情况下,在观测工具中,pgss 被认为是获取查询延迟信息的最通用方式。其重要性怎么估计都不为过 — 例如:
23+
- 如果我们知道通常情况下,平均查询持续时间 <1 ms,那么任何升至 10 ms 的情况都应被视为一个严重事件 (如果这是在部署后发生的,应该重新考虑或回滚该部署)。在故障排除时,它还能帮助我们进行分段分析,确定哪些特定查询组导致了延迟的升高 — 是所有查询组,还是只有特定的一些?
24+
- 在许多情况下,这可以被视为大型负载测试和基准测试中最重要的指标 (例如:比较 PG 15 和 PG 16 的平均查询持续时间,以便为升级到 PG 16 做准备)。
25+
- `dM/dc`,当 `M``rows` 时——这是查询组中查询返回的平均行数。对于 OLTP 场景来说,具有较大值的查询组 (起始值为几百或更多,具体取决于情况) 应进行审查:
26+
- 如果这是有意为之 (例如,数据导出),则无需采取行动;
27+
- 如果这是面向用户的查询,并且与数据导出无关,那么可能存在错误,例如缺少 `LIMIT` 和适当的分页,应该修正这些查询。
28+
- `dM/dc`,当 `M``shared_blks_hit + shared_blks_read` 时 — 这是查询组中缓冲池的平均 "命中数" + "读取数"。可以将其转换为字节进行分析:例如,`500,000` 次缓存命中和读取转换为 `500000 GiB * 8 / 1024 / 1024 ≈ 3.8 GiB`,这是单个查询中的一个显著数值,尤其是在查询目标仅仅返回一行或几行的情况下。对于较大的值,应考虑对查询进行优化。补充说明:
29+
- 在许多情况下,单独分析命中和读取的情况也是有意义的 — 例如,某些 pgss 查询组中的查询可能不会导致高磁盘 IO 和页面缓存读取,但在缓存池中的命中数非常多,尽管所有数据都缓存于缓存池中,但其性能仍不理想。
30+
- 要获取实际的磁盘 IO 数值,建议使用 [pg_stat_kcache](https://github.com/powa-team/pg_stat_kcache)
31+
- 如果某个查询组的此指标值突然发生变化,并且这种变化持续了一段时间,可能是执行计划发生了变化,需要进一步研究。
32+
- 高层聚合值也是观察的重点,例如回答类似 "该服务器上所有查询平均读取了多少 MiB?" 的问题。
33+
- `dM/dc`,当 `M``wal_bytes`(PG13+)时 — 这是查询组生成的平均 WAL 大小,单位是字节。它有助于识别哪些查询组对 WAL 的生成贡献最大。所有 pgss 记录的"全局"聚合值代表了服务器上所有语句的平均 WAL 字节数。对于 `dM/dc`(`M``wal_fpi`),在检查点调优场景中,跟踪其变化非常有用:当 `full_page_writes = on` 并且增加检查点之间的距离时,我们应该观察到该值的下降,研究不同的 pgss 组也可能很有意义。
34+
35+
---
36+
37+
明天我们将完成关于 pgss 相关的第三步教程。

0 commit comments

Comments
 (0)