1

Windows で PostgreSQL 8.3 を使用する C++ アプリケーションがあります。libpq インターフェイスを使用します。

各スレッドが接続を開き、PQFinish なしで使用し続けるマルチスレッド アプリがあります。

各クエリ (特に SELECT ステートメント) で、postgres.exe のメモリ消費量が増加することに気付きました。1.3 GB まで上がります。最終的に、postgres.exe がクラッシュし、プログラムに新しい接続を強制的に作成させます。

以前にこの問題を経験した人はいますか?

編集: shared_buffer は現在、conf で 128MB に設定されています。ファイル。

EDIT2: 現在実施している回避策は、すべてのトランザクションに対して PQfinish を呼び出すことです。ただし、毎回接続を確立するのは非常に遅いため、処理が少し遅くなります。

4

3 に答える 3

4

PostgreSQLでは、各接続に専用のバックエンドがあります。このバックエンドは、接続とセッションの状態を保持するだけでなく、実行エンジンでもあります。バックエンドは、横に置いたままにしておくのは特に安価ではなく、アイドル状態の場合でもメモリと同期のオーバーヘッドの両方がかかります。

特定のワークロード上の特定のPgサーバーに対して、アクティブに動作するバックエンドの最適な数があります。動作するバックエンドを追加すると、速度が上がるのではなく、速度が低下します。そのポイントを見つけて、バックエンドの数をそのレベル程度に制限する必要があります。残念ながら、これには魔法のレシピはありません。ほとんどの場合、ハードウェアとワークロードのベンチマークが含まれます。

それ以上の接続が必要な場合は、「接続状態」と「実行エンジン」を分離できるプロキシまたはプーリングシステムを使用する必要があります。2つの人気のある選択肢は、PgBouncerPgPool-IIです。アプリからプロキシ/プーラーへの軽量接続を維持し、データベースサーバーが最適な負荷で動作し続けるようにワークロードをスケジュールすることができます。入ってくるクエリが多すぎる場合、リソースを奪い合ってサーバー上のすべてのクエリの速度を落とす代わりに、実行されるまで待つものもあります。

postgresqlwikiを参照してください。

ワークロードがほとんど読み取られる場合、特に頻繁に変更されないアイテムがあり、信頼できるキャッシュ無効化スキームを決定できる場合は、memcachedまたはRedisを使用してデータベースのワークロードを減らすこともできます。これには、アプリケーションの変更が必要です。PostgreSQLのLISTENNOTIFYは、適切なキャッシュの無効化を行うのに役立ちます。

多くのデータベースエンジンには、実行エンジンと接続状態の分離がコアデータベースエンジンの設計に組み込まれています。Sybase ASEは確かにそうですし、Oracleもそうだと思いますが、後者についてはよくわかりません。残念ながら、PostgreSQLの接続ごとに1つのプロセスのモデルのため、バックエンド間で回避策を渡すのは簡単ではなく、PostgreSQLがこれをネイティブに行うのが難しくなるため、ほとんどの人がプロキシまたはプールを使用します。

PostgreSQLHighPerformanceを読むことを強くお勧めします。私はGregSmithや発行元とは何の関係もありません*。DBのパフォーマンスが気になる場合は、すばらしいと思います。


* ...まあ、私がこれを書いたとき、私はしませんでした。私は今同じ会社で働いています。

于 2012-04-18T11:37:35.863 に答える
1

メモリ使用量は必ずしも問題ではありません。PostgreSQLは一部のキャッシュに共有メモリを使用します。このメモリは、実際に使用されるまで、プロセスのメモリ使用量のサイズにはカウントされません。プロセスを使用すればするほど、共有バッファの大部分がそのアドレス空間でアクティブになります。

shared_buffersの値が大きい場合、これが発生します。サイズが大きすぎると、プロセスのアドレススペースが不足してクラッシュする可能性があります。

于 2009-08-01T15:37:41.577 に答える