问题背景:
业务使用的为磐维分布式版本oracle兼容模式,业务用户通过dbeaver执行sql语句,执行成功后返回结果集,并关闭结果集窗口。过一段时间后,数据库不可用。
问题现象:
dn6磁盘使用率达到85%,数据库只读。
问题分析:
系统资源排查,2025年5月21日早上09:49,业务数据库dn6节点临时文件开始激增,5月22日早上08:00,磁盘使用率达到85%,数据库只读。
关于pgsql_tmp的解释:
Temporary files (for operations such as sorting more data than can fit in memory) are created within PGDATA/base/pgsql_tmp, or within a pgsql_tmp subdirectory of a tablespace directory if a tablespace other than pg_default is specified for them. The name of a temporary file has the form pgsql_tmpPPP.NNN, where PPP is the PID of the owning backend and NNN distinguishes different temporary files of that backend.
可以知道temp文件是由会话ID:PId组成, 是SQL执行期间产生的临时性质的文件, 比如用于超大数据集排序等....一般在会话结束后会自动消除。
通过pgsql_tmpw文件夹中获取的pid,查询statement/pg_stat_activity视图,获取正在执行的sql,同时执行了多次此sql。并占用会话内存超过work_mem=8MB,达到44MB,同时执行多次。
当查询要使用的内存超出work_mem的大小时(包括排序,DISTINCT,MERGE JOIN,HASH JOIN,笛卡尔积,哈希聚合,分组聚合,递归查询等操作),会使用临时文件来存储中间过程的数据。如果频繁的进行上述操作,临时文件将会快速增长。
通过检查SQL的执行计划发现: 导致临时文件激增原因是因为该SQL导致的,SQL执行查不出来结果是因为在条件中缺少a、b表和d、e、f、g、h表的关联,导致a、b两个表的结果集和d、e、f、g、h结果集做了笛卡尔积,所以导致查询非常缓慢。
规避方法:
临时调整只读参数,恢复数据库环境,发现临时文件仍然激增,通过检查pid所在的会话信息,排查导业务sql执行,并且会话占用内存为44MB。持续一天会话状态active。通过select pg_terminate_backend (xxxxx);停止对应的线程运行后,将自动清空所有临时文件,释放磁盘空间。
解决方法:
优化sql,在SQL中引入关联表,将a、b表和d、e、f、g、h表通过条件进行关联可以优化SQL执行效率。
排查思路:
- 通过df -h/du -sh 逐级排查哪个目录占用,导致硬盘使用比率到85%。
- 查看pgsql_tmp文件夹下面的文件,根据命名规则获取大文件的pid。
- 查询pg_stat_activity/statement视图,获取正在执行的sql。
- 执行select pg_terminate_backend(‘pid号’);干掉sql,释放空间。
- 分析、优化已经获取到的sql。
问题总结:
系统资源排查,2025年5月21日早上09:49,业务数据库dn6节点临时文件开始激增,5月22日早上08:00,磁盘使用率达到85%,数据库只读。获取异常sql,临时规避方案,干掉异常sql释放空间,恢复业务。最终解决方法:优化sql,在SQL中引入关联表,将a、b表和d、e、f、g、h表通过条件进行关联可以优化SQL执行效率。




