web-dev-qa-db-ja.com

ディスク使用量が少ないにもかかわらず、PostgreSQLからのディスク容量不足エラーを診断する

PostgreSQL9.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?

EC2/RDSで実行されており、ディスク容量が少ないものは見つかりません。 EC2インスタンスには9GBのドライブがあり、使用率はわずか38%です。 RDS PostgreSQLデータベースには20GBのストレージがあり、使用率はわずか1%です。これはEC2インスタンスのiノードが少ない問題かもしれないと思いましたが、df -iは、33%しか使用されていないことを示しています。

このエラーの原因は何ですか?

3
Cerin

PostgreSQLが一時ファイルを書き込むためのスペースを使い果たしているため、このエラーが発生します。使用可能なスペースに対して大きすぎる一時テーブルをデータベースがときどき書き出す原因となるクエリが少なくとも1つあります。

デフォルトでは、postgresqlはtemp_tablespaces構成に空の文字列を使用します。これは、一時テーブルがデフォルトのテーブルスペース(別名$ DATA_DIR)に書き込まれることを意味します。 RDS Postgresを使用しているので、その設定が何を使用しているかを確認する必要があります

select * from pg_settings where name='temp_tablespaces';

上記のブロック位置と8192のRDSブロックサイズを使用すると、20 GB近くの一時テーブルを書き出しているように見えますが、これは偶然ではなく、そのデータベースクラスター用のテーブルスペースの量です。

これは、データベースの内容の倍数である一時テーブルを作成する病理学的クエリがあることを示唆しています。データベースに送信されるすべてのクエリをログに記録してみて( 例についてはaws docs を参照)、誤って実行している場所を特定できるかどうかを確認してください。 2つのテーブルのデカルト結合と出力のフィルタリング(または悪いクエリがとった可能性のある形式)。

temp_file_limit制限を適切な値に設定することをお勧めします(4GBを使用します)が、制限に早く到達するため、根本的な問題がより明確になります。

これに対する本当の解決策は、その一時的なスペースをすべて使用する原因となっているクエリを見つけて分離することです。最も簡単な方法は、SQLで取得し、Django ORMがそれを生成している理由を理解することです。

9
Larry