最も可能性の高い原因は、確かにメモリ不足のように聞こえます。これらが Linux サーバーの場合、メモリ不足状態をトリガーすると、「OOM-killer」が呼び出され、メモリ ホグ プロセスが単純に終了されます (したがって、「サーバーはプロセスを異常終了しました」)。メモリ不足の状況は、多くの場合、ディスク スワッピング/ページングの負荷が非常に高いことを意味し、サーバーが応答していないように見えます。
dmesg
" " に似たものがないか、カーネル ログ ファイル (またはコマンド) を参照してくださいOut of Memory: Killed process 1234 (postgres)
。これは、カーネルがメモリをオーバーコミットすることを許可するデフォルトが原因です。最初に行うべきことは、オーバーコミットを無効にして、メモリ不足の状況を適切に処理できるようにすることです。
echo 2 > /proc/sys/vm/overcommit_memory
プランA:
原因として考えられるのは、work_mem
個々の操作ごとに割り当てることができるメモリの量を指定する設定です。1 つのクエリは、メモリを集中的に使用する複数のステップで構成される場合があるため、各バックエンドは、グローバル設定に加えて、数倍のwork_mem
量のメモリを割り当てることができます。さらに、オペレーティング システムのキャッシュ用の空きメモリも必要です。shared_buffers
詳細については、リソース消費設定に関する PostgreSQL マニュアルを参照してください: PostgreSQL 8.3 ドキュメント、リソース消費
次の手段:
これらのチューナブルを減らすと、クエリが非常に遅くなり、まだ作業が完了しない可能性があります。これに代わる方法は、並行して実行できるクエリの数を人為的に制限することです。PostgreSQL の接続プールミドルウェアの多くは、並列クエリの数を制限し、代わりにキューイングを提供できます。このソフトウェアの例としては、pgbouncer (より単純) とpgpool -II (より柔軟) があります。
EDIT:あなたの質問に答える:
アプリケーションで多数の接続を処理するための最良/最適な方法は何ですか?各クエリの後に破棄する必要がありますか?
一般に、PostgreSQL への新しい接続の確立は高速ではありません。これは、PostgreSQL がバックエンドごとに新しいプロセスを生成するためです。ただし、プロセスはメモリの点で安価ではないため、データベースへのアイドル状態の接続を多数維持することはお勧めできません。
プラン Bで述べた接続プーリング ミドルウェアは、いつ、どのくらいの頻度でプーラーに接続または切断するかに関係なく、Postgres への妥当な数の接続を維持します。したがって、そのルートを選択すると、接続を手動で開いたり閉じたりすることを心配する必要はありません。
次に、 max_connections を増やす必要がありますか?
データベース サーバーに大量の RAM (8 GB 以上) がない限り、既定の制限である 100 接続を超えることはありません。