我正在运行一个非常大的查询,向表中插入了很多行,几乎有800万行被分成一些较小的查询,但在某个时刻出现了错误:“我遇到了错误“无法写入块……临时文件上没有剩余空间…。”使用PostgreSQL”。我不知道是否需要在每个查询之后删除临时文件以及如何操作,或者它是否与其他问题相关。
谢谢
我正在运行一个非常大的查询,向表中插入了很多行,几乎有800万行被分成一些较小的查询,但在某个时刻出现了错误:“我遇到了错误“无法写入块……临时文件上没有剩余空间…。”使用PostgreSQL”。我不知道是否需要在每个查询之后删除临时文件以及如何操作,或者它是否与其他问题相关。
谢谢
好的。由于还有一些事实缺失,尝试回答可能澄清这个问题:
看起来您的磁盘空间不足,很可能是因为磁盘上没有足够的空间。例如,在Linux / Unix上运行 df -h
检查。
为了向您展示如何发生这种情况: 假设有一个带有3个整数的表,仅数据就将占用约12个字节。您需要为行管理等添加一些开销。在另一个答案中,Erwin提到了23Byte,并链接到手册以获取更多信息。还可能需要在行之间添加一些填充。因此进行一些计算:
即使只有3个整数,我们也会最终达到每行约40个字节。请记住,您想插入800万行,这将总计达到320,000,000字节或〜300MB(仅针对我们的3个整数示例,非常粗略地计算)。
现在假设,您的这个表上有几个索引,这些索引也会在插入过程中增长。还有另一个方面可能是表和索引上的膨胀,可以使用vacuum将其清除。
那么解决方案是什么:
vacuum
只会清除已被删除或更新的过时行。insert
永远不会创建符合清理条件的行。 - user330315VACUUM
永远不会将存储返回给操作系统(VACUUM FULL
会,但它需要大量的开销空间来工作,并且除非有很多死行,否则它不会有所帮助)。 - Daniel Lyons插入数据或索引(创建)始终需要temp_tablespaces,它确定临时表和索引的位置,以及用于排序大数据集等目的的临时文件。根据您的错误,意味着您的temp_tablespace位置的磁盘空间不足。
要解决此问题,您可以使用以下两种方法:
1. 重新声明位于temp_tablespace的空间,默认为/PG_DATA/base/pgsql_tmp
2. 如果您的temp_tablespace空间仍然不足以进行临时存储,可以为该数据库创建其他临时表空间:
create tablespace tmp_YOURS location '[your enough space location';
alter database yourDB set temp_tablespaces = tmp_YOURS ;
GRANT ALL ON TABLESPACE tmp_YOURS to USER_OF_DB;
然后断开会话并重新连接。