4

Django 1.3.1 と Postgres 9.1 を使用しています

データベースからデータを取得するために複数の選択を実行するだけのビューがあります。

Django ドキュメントでは、ビューの呼び出し中に select ステートメントのみが起動された場合、リクエストが完了すると ROLLBACK が発行されることが言及されています。しかし、特に 200 を超えるリクエストがある場合、ログに多くの "idle in transaction" が表示されます。postgres ログに commit または rollback ステートメントが表示されません。

何が問題なのですか?この問題をどのように処理すればよいですか?

4

2 に答える 2

5

まず、関連する投稿をチェックします。これは、いくつかの関連する地面をカバーしています。

「Idle in transaction」の原因の 1 つは、「BEGIN;」と入力した開発者またはシステム管理者である可能性があります。psql で「コミット」または「ロールバック」するのを忘れていました。そこに行ったことがある。:)

ただし、問題は多くの同時接続に関連していると述べました。上記の投稿の「ロック」のヒントを調査すると役立つようです。

さらにいくつかの提案: この問題は二次的なものである可能性があります。主な問題は、200 の接続がハードウェアとチューニングで快適に処理できる量を超えているため、すべてが遅くなり、物事が遅くなると、他のことが完了するのを待っているものが増えることです。

Web アプリの前に Nginx のようなリバース プロキシがない場合は、追加することを検討してください。ハードウェアを追加しなくても、同じホスト上で実行できます。リバース プロキシは、バックエンドの Django Web サーバーへの接続数、つまりデータベース接続数を調整する役割を果たします。以前、データベース接続が多すぎてここに来ましたが、これが解決方法です。

Apache の prefork モデルでは、Apache::DBI のようなものが使用されていると仮定すると、Apache ワーカーの数とデータベース接続の数の間に 1 = 1 の対応があります。誰かが低速の接続で Web サーバーに接続したとします。Web サーバーとデータベース サーバーは比較的迅速に要求を処理しますが、コンテンツがクライアントに戻ってくる間、不必要に Web サーバー上で要求が開かれたままになります。その間、データベース接続スロットは拘束されます。

リバース プロキシを追加することで、バックエンド サーバーは応答をリバース プロキシに迅速に送り返し、バックエンド ワーカーとデータベース スロットを解放することができます。その後、リバース プロキシはコンテンツをクライアントに返す責任を負い、おそらくそれ自体を開いたままにします。より長く接続します。前もってリバース プロキシへの接続が 200 あるかもしれませんが、バックエンドに必要なワーカーと db スロットははるかに少なくなります。

MRTG などで db スロットをグラフ化すると、実際に使用しているスロットの数がわかり、PostgreSQL の max_connections を調整して、それらのリソースを他の用途に解放できます。

また、pg_topを参照して、データベースの状態を監視することもできます。

于 2012-06-02T01:13:48.273 に答える
0

これは古い質問であることは理解していますが、この記事では django のアイドル トランザクションの問題について説明している可能性があります。

基本的に、Django の TransactionMiddleware は、ダーティとマークされていない場合 (通常はデータの書き込みによってトリガーされる)、トランザクションを明示的に COMMIT しません。それでも、読み取り専用であっても、すべてのクエリに対してトランザクションを開始します。そのため、pg は、さらにコマンドが来るかどうかを確認するために待機したままになり、アイドル状態のトランザクションが発生します。

リンクされた記事は、常にコミットするようにトランザクション ミドルウェアを少し変更したことを示しています (基本的に、トランザクションが is_dirty かどうかをチェックする条件を削除します)。まもなく、この修正を実稼働環境で試します。

于 2012-12-18T03:01:42.067 に答える