web-dev-qa-db-ja.com

ディスクの満杯に対処するPostgreSQLの戦略

私はPostgreSQL(8.4)を使用して、頻繁に挿入するアプリケーションによって生成されたデータを(以下に説明するテーブル構造に)格納しています。

データベースは時間とともに増大し続け、新しいデータは古いデータよりも関連性が高いため(この特定のアプリケーション)、古い行を削除することは合理的な解決策です(低いidまたは古いinput_datetimeに基づいて、ほぼ同じです)。

このデータベース(このサーバーで実行されている唯一のデータベース)に関連する問題がシステムの残りの部分に影響を与えないようにするため、PostgreSQLデータディレクトリを独自のパーティション(Linuxシステムではext3)に配置しました。それにもかかわらず、このパーティションがいっぱいになると、いくつかの問題が発生します。

これに対処するために、古いデータを定期的に削除する(たとえば、cronジョブを介してDELETE FROM data_group WHERE id <= ...)ことを考えています。

第一に、VACUUMの理解(オンになっているauto-vacuumによって実行される)は、必ずしも(VACUUM FULLがそうであるように)OSにディスク領域を返すとは限りませんが、すでに使用されているディスク領域内に挿入される新しいデータ(つまり、DELETEsは必ずしもファイルサイズに影響を与えるわけではありませんが、PostgreSQLのデータ構造で領域を解放します)。これは正しいです? (VACUUM FULLがアプリケーション自体にいくつかの問題を引き起こしていることに気付きました。おそらくそれが使用するロックが原因です。)

その場合、SELECT pg_database_size('my_database')はディスクで使用されているサイズを反映しているように見えます。これは、以降の挿入に使用できるサイズを必ずしも反映しているわけではありません。新しい挿入に使用できるスペースを見積もる別の方法はありますか?

さらに、手遅れでパーティションが100%になっている場合、このDELETEステートメントを実行すると、このエラーが発生し、PostgreSQLサービスがクラッシュします。

パニック:ファイル "pg_xlog/xlogtemp.7810"に書き込めませんでした:デバイスにスペースが残っていません

もちろん、PostgreSQLデーモンの停止は大きな問題です(このマシンでは、クラスターを移動するディスクが他にありません)。

この種の問題の発生を防ぐための一般的な戦略はありますか(ディスクスペースが特定のパーティション内で制限されていることを知っていますが、古いデータを削除しても問題ありません)? rootまたはpostgres(またはPostgreSQL管理者)の介入なしに、これを可能な限り自動化したいと思います。


CREATE TABLE data_group (
    id SERIAL PRIMARY KEY,
    name TEXT,
    input_datetime TIMESTAMPTZ
);

CREATE TABLE data_item (
    id SERIAL PRIMARY KEY,
    group_id INTEGER NOT NULL REFERENCES data_group(id) ON DELETE CASCADE ON UPDATE CASCADE,
    position INTEGER NOT NULL,
    data BYTEA
);
6
Bruno

一方で、テーブルサイズをほぼ一定に保つ方法を確認するために、以前の回答 の1つ を見ることができます。そこにはトリガーのある解決策があります-もちろん、これはcronジョブを使用しても解決できます。後者の場合、まず行番号が特定の制限を超えているかどうかを確認し、最も古い行を削除するか、パーティションを削除します。

一方、すでにお気づきのように、pg_xlogがあるディスク領域に注意する必要があります。いっぱいになると、簡単に回復することはできません...しかし、データベースの設定を確認することで、必要な容量を適切に見積もることができます。

常に少なくとも1つのWALセグメントファイルが存在し、通常は(2 + checkpoint_completion_target) * checkpoint_segments + 1またはcheckpoint_segments + wal_keep_segments + 1ファイルを超えません。各セグメントファイルは通常16 MBです(ただし、このサイズはサーバーの構築時に変更できます)。これを使用して、WALのスペース要件を見積もることができます。通常、古いログセグメントファイルが不要になると、それらはリサイクルされます(番号が付けられたシーケンスの次のセグメントになるように名前が変更されます)。ログ出力レートの短期間のピークにより、3 * checkpoint_segments + 1を超えるセグメントファイルがある場合、システムがこの制限を下回るまで、不要なセグメントファイルはリサイクルされずに削除されます。

レプリケーションを設定していない場合、最大は3 * checkpoint_segments + 1(16 MB倍)です。典型的なレプリケーションなしのセットアップでは、pg_xlogに10 GB未満が必要になると思います。

4
dezso