PostgreSQL 13中WITH语句(CTE)无法被日志记录的问题咨询
PostgreSQL 13 CTE语句日志不记录解决方案
你当前配置的log_statement = 'all'理论上会记录所有客户端直接提交的顶层SQL语句,包括WITH开头的CTE语句,PostgreSQL没有专门针对CTE的日志过滤规则,出现不记录的情况可以按以下步骤排查解决:
1. 确认配置已正确生效
- 改完
postgresql.conf后必须执行配置重载命令:SELECT pg_reload_conf(); - 执行以下命令验证配置值:
SHOW log_statement; SHOW logging_collector;
确保返回值分别为all和on,如果不符合说明配置文件修改有误或者没有正确重载。
2. 排查语句执行方式问题
如果是通过应用端ORM、连接池提交的CTE语句,大多驱动会默认把这类语句转为预备语句(PREPARE)执行,默认配置下预备语句的执行不会被log_statement = 'all'捕获,需要追加配置:
log_prepared_statements = on
重载配置后即可记录预备语句的内容和执行请求。
如果需要记录所有执行的语句(包括内部调用的语句),也可以补充配置:
# 注意:生产环境开启会产生大量日志,评估磁盘容量后再设置 log_min_duration_statement = 0
3. 排查嵌套执行场景
如果CTE语句是在函数、存储过程、触发器内部执行的,默认log_statement只会记录客户端提交的顶层调用语句,不会记录函数内部的SQL,需要针对使用的过程语言配置日志,比如常用的plpgsql:
plpgsql.log_statements = 'all'
开启后即可记录plpgsql代码块内部执行的所有SQL语句。
4. 验证测试
直接通过psql命令行工具连接数据库,手动执行你给出的CTE样例语句:
with table_a as (select 1+1 as total), table_b as (select 2+2 as total), table_c as (select 3+3 total) select a.total*b.total* c.total from table_a as a, table_b as b, table_c as c;
执行后直接查询最新的日志文件,如果该语句被正常记录,说明问题出在应用端的连接/执行逻辑,按步骤2配置即可解决;如果psql执行也不记录,检查是否有其他日志过滤参数(比如log_exclude_function、自定义的日志钩子插件)拦截了语句输出。
内容的提问来源于stack exchange,提问作者user17607210
相关产品推荐
相关产品推荐

