暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

postgresql 防止磁盘空间被撑爆

原创 鸿惊九天 2022-12-16
2276

设置 temp_file_limit ,防止磁盘空间被撑爆(一大堆排序SQL)

问题

空间被撑爆,简单的看了一下,空间主要增长是临时文件。

[postgresql@133e0e148e21 base]$ du -sm *8 18 135908 13591120125 16444271460 pgsql_tmp

临时文件的产生一般都是大型的排序、去重、hash等操作导致的,我们通过pg_stat_activity视图查看当前活动会话的情况。

select pid,wait_event,wait_event_type,query from pg_catalog.pg_stat_activity;

可以看到当前主要活动的一些会话,都在执行一个order by分页查询的SQL。

通过查询这个order的表。发现它居然高达54GB。
zys=> \dt+ zys_man_oltaccess_push

于是赶紧联系了应用,把这一批SQL杀掉之后,系统就恢复了正常。
zys=> select ‘pg_catalog.pg_terminate_backend(’||pid||’)’ from pg_catalog.pg_stat_activity where query like ‘%offset%’;

这个故障并不复杂,问题是在于这套库我们并没有对这方面做任何控制。
如果是Oracle数据库,我们一般都会建个Temp表空间,然后设置为30-60GB,一旦出现问题,像应用搞了大的SQL,会导致临时文件撑爆,最终导致执行的SQL失败。并不会导致像我们这种整个目录空间撑爆的问题。

所以PostgreSQL应该怎么像Oracle一样进行限制,防止大的垃圾SQL把空间撑爆了?

答案是使用temp_file_limit参数进行限制。该参数的默认值为-1(不限制),最大值是2147483647kB,换算过来大概是2TB。

我搜了一下,建议是把该值的大小设置成为整个目录空间的10%。我这里是1TB,那么我先暂时设置成50GB测试一下。

zys=# alter system set temp_file_limit=52428800;
ALTER SYSTEM
zys=# select pg_reload_conf();

再次执行查询
zys=> select * from zys_man_oltaccess_push order by prod_inst_id limit 10000 offset 5850000;

这次在达到我们设置的50GB,就不再增长。而且结果也能顺利的查询出来。

但是这样设置也会问题,就是一个进程能创造的最大文件是50GB,但是进程一旦并发起来,比如10个进程同时run,还是会占用500GB,这仍然是一个很大的占用。

如果我们把这个值设置的足够小。比如5GB,我们再次执行这个查询,这次就会报temporary file size exceeds temp_file_limit (5242880kB)

zys=# alter system set temp_file_limit=5242880;
ALTER SYSTEM
zys=# select pg_reload_conf();
zys=> select * from zys_man_oltaccess_push order by prod_inst_id limit 10000 offset 5830000;
ERROR: temporary file size exceeds temp_file_limit (5242880kB)CONTEXT: parallel worker

应用程序执行的SQL语句就会报错。

所以暂时没什么好的办法,只能加强监控,通过设置log_temp_files,默认值是-1。可以将排序,哈希等操作创建的临时文件进行跟踪记录。然后就可以知道应用的这些SQL需要搞多少的临时文件了。然后再根据它们的并发合理设置一个值。

pg_stat_database有两个字段,分别是temp_files和temp_bytes,它们都是累计值。
temp_files代表数据库创建的临时文件数,temp_bytes代表数据库创建的临时文件空间总大小。
zys=> select datname,temp_files,temp_bytes from pg_stat_database where datname=‘zys’;

我们可以通过prometheus对文件产生的速率进行监控。

「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论