Cer*_*rin 3 postgresql amazon-ec2 amazon-rds postgresql-9.3
我有一个使用 PostgreSQL 9.3 数据库的 Django Web 应用程序,它偶尔会抛出错误:
File "/usr/local/my_site/.env/lib/python2.7/site-packages/django/db/utils.py", line 94, in __exit__
six.reraise(dj_exc_type, dj_exc_value, traceback)
File "/usr/local/my_site/.env/lib/python2.7/site-packages/django/db/backends/utils.py", line 64, in execute
return self.cursor.execute(sql, params)
OperationalError: could not write block 2432320 of temporary file: No space left on device
HINT: Perhaps out of disk space?
Run Code Online (Sandbox Code Playgroud)
它在 EC2/RDS 上运行,我找不到任何磁盘空间不足的东西。EC2 实例有一个 9GB 驱动器,仅使用了 38%。RDS PostgreSQL 数据库有 20GB 的存储空间,只有 1% 的使用率。我认为这可能是 EC2 实例上的低 inode 问题,但df -i
显示仅使用了 33%。
什么会导致这个错误?
小智 9
您收到此错误是因为 PostgreSQL 空间不足,无法写入临时文件。您至少有一个查询会导致数据库偶尔写出一个对于可用空间来说太大的临时表。
默认情况下,postgresql 使用空字符串进行temp_tablespaces
配置;这意味着临时表被写入默认表空间(也就是你的 $DATA_DIR )。由于您使用的是 RDS Postgres,因此您必须查看该设置使用的内容
select * from pg_settings where name='temp_tablespaces';
鉴于提到的块位置并使用 RDS 块大小 8192。看起来您正在写出近 20GB 的临时表,这并非巧合的是您为该数据库集群拥有的表空间量。
这表明您有一个病理查询,该查询构建了一个临时表,该表是数据库内容的倍数。您应该尝试记录进入您的数据库的所有查询(示例参见 aws 文档),看看您是否可以发现您不小心对两个表进行笛卡尔连接并过滤输出的位置(或您的错误查询可能具有的任何形式)采取)。
您可能希望将temp_file_limit
限制设置为一个合理的值(我会选择 4GB ),但这只会使潜在问题更加明显,因为您会更早地达到限制。
真正的解决方案是找到并隔离导致您使用所有临时空间的查询。最简单的方法是在 sql 中获取它并找出 Django ORM 生成它的原因。