PostgreSQL查询pg_stat_statements产生临时文件的疑问
可能的核心原因
尽管查询没有显式排序或连接操作,但临时文件的出现往往和隐式内存需求超出work_mem限制或服务器/表的特殊状态有关,针对你的场景,重点排查以下几点:
pg_stat_statements元数据量差异
这台服务器的pg_stat_statements表可能积累了远多于其他节点的语句记录——比如长期未清理、业务量更大、语句类型更繁杂。当查询全表时,即使没有显式排序,聚合类操作(比如count、sum)如果数据量超过work_mem,PostgreSQL会切换到磁盘哈希聚合,进而产生临时文件。统计信息失效
该服务器的pg_stat_statements表统计信息可能未及时更新,导致优化器错误估算数据规模,选择了需要更多临时存储的执行路径。手动执行ANALYZE pg_stat_statements;后,再对比执行计划是否变化。work_mem未实际生效
work_mem是会话级参数,pmm-agent执行查询时可能使用独立的会话配置,并未继承你修改的全局设置。可以检查pmm-agent的连接配置,或者在其执行查询的会话中执行SHOW work_mem;,确认是否真的应用了300MB的设置。操作系统层面内存限制
这台服务器可能存在cgroup、ulimit等操作系统级别的内存限制,导致PostgreSQL无法实际分配到300MB的work_mem,被迫使用临时文件。可以用ulimit -a查看进程内存限制,或者检查cgroup的内存配额配置。pg_stat_statements配置差异
虽然所有节点都部署了扩展,但这台服务器的pg_stat_statements.track参数可能设置更严格(比如all而非top),导致记录的语句量暴增;或者扩展在编译/升级过程中存在异常。可以对比节点间SELECT * FROM pg_extension WHERE extname='pg_stat_statements';的结果,以及pg_stat_statements相关GUC参数的差异。
验证步骤
- 对比异常节点与正常节点的
pg_stat_statements表行数:SELECT count(*) FROM pg_stat_statements;,确认是否存在数量级的差距。 - 手动执行pmm-agent的目标查询,同时通过
SELECT temp_files, temp_bytes FROM pg_stat_activity WHERE query LIKE '%pg_stat_statements%';确认临时文件是否由该查询产生。 - 对目标查询执行
EXPLAIN (ANALYZE, BUFFERS),对比正常节点的执行计划,重点查看是否有Hash Aggregate等操作标注了Disk: xxx,这是使用磁盘聚合的明确信号。 - 确认pmm-agent会话的work_mem实际值:在查询执行时,找到对应的会话进程,执行
SHOW work_mem;验证配置。
内容的提问来源于stack exchange,提问作者Anton P

