PostgreSQL 如何记录所有执行的 SQL 查询?

PostgreSQL 可用 log_statement = 'all' 记录相应语句;写 collector 文件时另启用 logging_collector,解析前错误等路径需其他日志设置。本文给出配置步骤及替代方案 log_min_duration_statement。

最佳实践
PostgreSQL 如何记录所有执行的 SQL 查询?封面

核心配置:在 postgresql.conf 中取消注释并修改 log_statement = 'all'、logging_collector = on,重启 PostgreSQL 后符合该日志机制的语句会记录到所配置目的地;all 不覆盖解析前错误等所有可能路径。生产环境慎用 all,建议用 log_min_duration_statement 只记慢查询。

配置步骤

编辑 postgresql.conf(通常在数据目录或 /etc/postgresql/ 下):

logging_collector = on
log_directory = 'pg_log'
log_filename = 'postgresql-%Y-%m-%d_%H%M%S.log'
log_statement = 'all'

重启 PostgreSQL:

# 服务名依集群和发行版而定,先确认实际实例
sudo systemctl restart postgresql
# 或
sudo service postgresql restart

日志文件位于数据目录的 pg_log/ 子目录中。

运行时持久修改

ALTER SYSTEM SET log_statement = 'all';
SELECT pg_reload_conf();

ALTER SYSTEM 写入持久配置,不是临时开关。排查后恢复原值或 RESET 并 reload;需有相应管理权限。collector 的启用需要重启,但 log_statement 可重载,syslog/stderr 等目的地不都要求 collector。

各 log_statement 级别对比

值 记录内容
none 不由 log_statement 记录语句(默认),其他错误/慢日志机制仍可记录
ddl CREATE、ALTER、DROP 等结构变更
mod ddl + INSERT/UPDATE/DELETE
all 所有语句(含 SELECT)

更推荐的方案

log_statement = 'all' 在高并发下会产生大量日志影响性能。更实用的做法是:

log_min_duration_statement = 500   # 记录执行超过 500ms 的语句及其耗时

启用后先确认实际日志路径和一条慢查询记录。需要集中检索时,可用观测云 DataKit 文件采集读取该路径,并用日志样本检查多行合并与时间解析;采集前应检查 SQL 是否含敏感参数。

常见问题(FAQ)

Q:log_statement = 'all' 对性能影响大吗?
A:会。每条 SQL 都要写日志,高并发下 I/O 开销明显,且日志文件会快速增长。建议只用于短期调试。

Q:日志文件路径在哪?
A:相对路径基于数据目录。查看数据目录位置:SHOW data_directory;。本例目录为 {数据目录}/pg_log/;实际应查看 log_destination、logging_collector、log_directory,启用 collector 时可用 pg_current_logfile() 辅助定位。

Q:能只记录某个用户的查询吗?
A:可以:ALTER USER app_user SET log_statement = 'all';,对该角色随后新建的会话应用默认值;已有会话不会自动改变,还需注意会话级覆盖及管理权限。

获取专属方案

联系我们

加入社区

微信扫码
加入官方交流群

立即体验

在线开通,按量计费,真正的云服务!

立即开始

选择观测云版本

代码托管平台