慢查询日志:log_min_duration_statement 与 auto_explain 怎么配
打开慢查询日志只要一个参数,但"日志里有执行计划"要另一个模块。两者组合起来,才不用等问题复现时再手打 EXPLAIN。
1. 一条真实日志行
把 log_min_duration_statement 设成 50ms 之后,跑一条三百万行的聚合,容器日志里出现:
2026-11-10 05:53:46.717 UTC [189] LOG: duration: 235.422 ms statement: select count(*) from generate_series(1,3000000);
三段信息:log_line_prefix 里的时间与 pid、duration、原始语句。默认 log_line_prefix 就是 %m [%p] 。
2. 相关参数与默认值
| 参数 | 默认值 | 说明 |
|---|---|---|
log_min_duration_statement | -1(关闭) | 超过该毫秒数的语句记日志;0 表示全记 |
log_statement | none | 按语句类型记(ddl/mod/all),与上者独立 |
log_duration | off | 只记耗时、不记语句文本 |
log_line_prefix | %m [%p] | 建议加上 %u@%d,否则不知道是谁、哪个库 |
logging_collector | off | 容器里通常保持关闭,日志走 stderr |
log_lock_waits | off | 打开后记录等锁超过 deadlock_timeout 的语句 |
log_temp_files | -1 | 设为 0 记录所有临时文件,排查排序落盘很有用 |
改法:ALTER SYSTEM SET log_min_duration_statement = '200ms'; 然后 SELECT pg_reload_conf();。这个参数是 superuser 级,改配置文件或 reload 都行。
3. auto_explain:把执行计划写进日志
auto_explain 是 contrib 模块,加载后可以自动记录慢语句的计划。官方给的最小配置:
# postgresql.conf
session_preload_libraries = 'auto_explain'
auto_explain.log_min_duration = '3s'
关键参数:
| 参数 | 默认 | 说明 |
|---|---|---|
auto_explain.log_min_duration | -1 | 不设就什么都不记 |
auto_explain.log_analyze | off | 打开后等价于 EXPLAIN ANALYZE,会记录每个节点的实际耗时 |
auto_explain.log_buffers | off | 需要先开 log_analyze |
auto_explain.log_timing | on | 关闭可降低计时开销 |
auto_explain.log_format | text | 可选 json,便于采集 |
auto_explain.sample_rate | 1 | 采样比例,高流量下用它降噪 |
日志形如:
LOG: duration: 3.651 ms plan:
Query Text: SELECT count(*) FROM pg_class ...
Aggregate (cost=16.79..16.80 rows=1 width=0) (actual time=3.626..3.627 rows=1.00 loops=1)
4. 三个会拖慢性能的开关
log_analyze 让每条被记录的语句都做逐节点计时。官方文档明确说这"可能对性能有极大的负面影响",因为它对所有语句生效,不只看慢的。生产上先只记 duration,需要计划时再按需打开或调大阈值。
log_statement = 'all' 会在高峰期产生巨量日志,磁盘写满的风险比你看清问题更快到来。
log_duration = on 单独用没有语句文本,排查时几乎没用;它和 log_min_duration_statement 同时开会出现重复条目。
小结
配置顺序:先 log_min_duration_statement(比如 200ms)加 log_line_prefix 里的用户与库名,拿到"哪条语句慢";再按需上 auto_explain 拿"为什么慢"。
两个模块的默认值都是温和的(-1、off),所以"我配了但没日志"通常不是故障,是阈值还在关闭状态。改完用一条 pg_sleep(1) 验证一下最省事。
数据来源与检索时间
检索时间 2026-11-10。第一节日志行与本机默认值来自实测。
| 来源 | URL | 对应数据 |
|---|---|---|
| PostgreSQL 18 文档《auto_explain》 | https://www.postgresql.org/docs/18/auto-explain.html | 模块加载方式、各参数默认值、log_analyze 的性能警告、示例日志格式 |
| PostgreSQL 18 文档《19.8 错误报告与日志》 | https://www.postgresql.org/docs/18/runtime-config-logging.html | log_min_duration_statement、log_statement、log_line_prefix、log_lock_waits、log_temp_files 的语义与默认值 |
核验说明
- 第一节的日志行为本机 18.6 实跑(
ALTER SYSTEM+pg_reload_conf()后触发一条 235ms 语句),默认值来自pg_settings实查。 - 未做:没有在开启
auto_explain的情况下测性能影响(需要重启并加载模块),该结论依据文档的性能警告;也没有验证log_format=json的采集链路。