第 27 章 精益求精:参数调优与资源治理
调优不是把一份“最佳参数”复制到 postgresql.conf。
同一个参数变化可能:
让一条查询更快
但让十条并发查询触发 OOM
减少 WAL
但增加 primary CPU 和 replica replay CPU
提高单条分析查询速度
但占满 parallel worker,让 OLTP tail latency 变差
增加连接槽
但把 pool 中可控的队列搬进数据库
在 benchmark 中提高 TPS
但降低 durability、HA headroom 或 recovery predictability本章用一条严格的推理链替代参数清单:
service objective
-> observed bottleneck or resource risk
-> parameter mechanism
-> scope and precedence
-> one-factor experiment
-> benefit + non-regression + failure behavior
-> rollback
-> ADR如果中间缺了一环,默认动作不是“先改了看看”,而是补证据。
参数不是独立旋钮
PostgreSQL 参数形成资源系统:
shared_buffers
<-> OS page cache
<-> checkpoint dirty-page work
<-> max_wal_size
work_mem
× active operations
× sessions
× parallel processes
× hash_mem_multiplier
max_connections
<-> backend/shared memory
<-> pool queue
<-> lock/context-switch pressure
parallel workers
<-> CPU
<-> work_mem
<-> worker pool
<-> other queries and maintenance
checkpoint / WAL
<-> write smoothing
<-> WAL volume
<-> archive/replica
<-> crash recovery time所以本章不按字母解释 GUC,而按资源预算和失效机制组织。
本章实验故意得到“拒绝改参”
第 26 章参考 run 提供了几个事实:
- c8 时 server work ratio 约 84%,client 未先饱和;
- workload 使用 prepared protocol;
- 六个 cell 的 temp bytes 全为零;
- L 档有 block read,但 server iowait 很低;
- 只有 c1/c8,精确 knee 未知;
- production sustainable TPS 仍为
null。
这些事实不支持:
increase work_mem
increase shared_buffers
increase max_connections
disable synchronous_commit它们只使一个假设值得被证伪:
prepared OLTP 在
plan_cache_mode=auto下是否仍承担了足够的 custom planning 成本,使force_generic_plan获得至少 2% 的稳定收益?
正式实验只改变这个参数,而且只用 PGOPTIONS 改 benchmark session:
baseline plan_cache_mode=auto
candidate plan_cache_mode=force_generic_plan固定 M 数据、8 clients、prepared、50/30/20 mix;五组 paired repetition 使用相同 seed,A/B 顺序交错。共 10 次 12 秒 measured run、357,685 笔事务:
| arm | median TPS | pooled p50 | pooled p95 | pooled p99 | failure/late/skipped |
|---|---|---|---|---|---|
auto | 2,981.72 | 1.279 ms | 9.217 ms | 13.127 ms | 0 |
force_generic_plan | 3,051.72 | 1.285 ms | 9.135 ms | 12.933 ms | 0 |
只看两个 median,candidate 好像快 2.35%。但正确的配对分析是:
paired TPS ratio median 1.00735
bootstrap 95% interval [0.98082, 1.02775]
candidate / baseline p95 0.99110
required bootstrap lower >= 1.02candidate 没有证明至少 2% 的稳定收益。plan probe 还发现:
auto:
first 5 custom + next 5 generic
force_generic_plan:
10 generic + 0 customPostgreSQL 的 auto 已经为这两类稳定 plan 自动转向 generic。强制 generic 只省掉
少量早期 planning,却可能伤害参数敏感查询。最终 ADR:
decision reject-persistent-change
persistent change applied false
production gate pending这不是“没有调优成果”。它避免了一项没有稳定收益、却扩大 plan risk 的持久变更。
公共结果见 tuning-run.json,完整安全边界见
lab-contract.md。
本章学习成果
完成本章后,你应该能:
- 从 SLO、bottleneck 和 non-regression 指标写调优假设;
- 区分参数、SQL/schema、workload 与 topology 问题;
- 为 shared memory、per-operation memory、maintenance 与 OS 留出完整预算;
- 解释
work_mem × 节点 × 并发 × parallel process的放大; - 用 WAL、checkpointer、I/O 与 recovery evidence 调整 checkpoint;
- 区分
effective_cache_sizeestimate 与真实 cache allocation; - 校准 cost parameter,而不是用
enable_seqscan=off长期逼 planner; - 计算 parallel worker 的 cluster budget 和降级行为;
- 把 connection limit 与 pool/admission、reserved slot 和 emergency access 联动;
- 从
pg_settings.context/source/pending_restart判断变更方式; - 从
pg_file_settings找出 syntax error 与被后项覆盖的配置; - 理解 system、database、role、role-in-database、session、transaction 的覆盖关系;
- 用 Pigsty template、
pg_parameters与 IaC 保持 desired state; - 在 reload/restart/rolling change 前写 failure、rollback 与 validation;
- 接受“拒绝修改”也是合格 ADR。
本章目录
27.1 调优是一套实验方法
27.2 内存预算
- 27.2.1 shared buffers、操作系统页缓存与双重缓存
- 27.2.2
work_mem按节点、并发和并行放大 - 27.2.3 maintenance、autovacuum 与后台进程内存
- 27.2.4 OOM 风险必须用最坏并发估算
27.3 WAL、检查点与写入平滑
27.4 规划器、并行与连接参数
27.5 参数作用域与变更方式
27.6 模板参数与集群变更
27.7 实战:只调一个已证实的瓶颈
阅读路线
应用开发者:
27.1 -> 27.2.2 -> 27.4 -> 27.5.2 -> 27.7重点是 per-query memory、plan、timeout、role/database scope 和 A/B。
平台工程师:
27.1 -> 27.2 -> 27.3 -> 27.5 -> 27.6 -> 27.7重点是 cluster resource budget、WAL/recovery、配置来源、IaC 与 rolling risk。
两条路线必须合流:应用知道 transaction 与 query shape,平台知道 failure domain 与 global resource envelope;任何一方单独调参都容易优化局部、破坏整体。
实验文件
static/labs/ch27/
├── requirements.json
├── parameter-candidates.json
├── change-contract.json
├── negative-cases.json
├── topology.mmd
├── lab-contract.md
├── setup.sql
├── reset-run.sql
├── read-product.sql
├── read-order.sql
├── place-order.sql
├── plan-probe-counts.sql
├── plan-probe-product.sql
├── plan-probe-order.sql
├── remote_experiment.py
├── capture.py
├── exercise.py
├── validate.py
├── review.py
├── task.sh
└── tuning-run.json实验:
- 只测试一个参数;
- 只在 benchmark session 生效;
- 不使用
ALTER SYSTEM、DCS edit、reload/restart; - 保留 raw transaction log 与 plan-shape evidence;
- 用 28 个对抗变体验证 target、scope、配对、quantile、decision 和 cleanup;
- 专用 database、role 与远端临时目录全部清理;
- 不管 candidate 接受或拒绝,production gate 都保持
pending。
参考资料
- PostgreSQL 18 server configuration
- PostgreSQL 18 setting parameters
- PostgreSQL 18 resource consumption
- PostgreSQL 18 WAL configuration
- PostgreSQL 18 query planning
- PostgreSQL 18
pg_settings - PostgreSQL 18
pg_file_settings - Pigsty parameter optimization policy
- Pigsty PostgreSQL parameter scopes
上一章:胸有成竹:容量规划与压测基线 · 返回下卷导读 · 下一章:除旧布新:VACUUM、冻结与膨胀治理 · 查看全书目录 · 查看索引中心