KernelRanch
返回文章列表

慢查询日志:log_min_duration_statement 与 auto_explain 怎么配

2026-11-10 #数据库

打开慢查询日志只要一个参数,但"日志里有执行计划"要另一个模块。两者组合起来,才不用等问题复现时再手打 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_statementnone按语句类型记(ddl/mod/all),与上者独立
log_durationoff只记耗时、不记语句文本
log_line_prefix%m [%p] 建议加上 %u@%d,否则不知道是谁、哪个库
logging_collectoroff容器里通常保持关闭,日志走 stderr
log_lock_waitsoff打开后记录等锁超过 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_analyzeoff打开后等价于 EXPLAIN ANALYZE,会记录每个节点的实际耗时
auto_explain.log_buffersoff需要先开 log_analyze
auto_explain.log_timingon关闭可降低计时开销
auto_explain.log_formattext可选 json,便于采集
auto_explain.sample_rate1采样比例,高流量下用它降噪

日志形如:

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.htmllog_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 的采集链路。