0

Apache2、mod_python、およびpostgresql_psycopg2データベースバックエンドを備えたPostgreSQL8.3を使用してDjangoで適度に人気のあるWebアプリを実行します。私は時折ライブロックを経験しています。これは、apache2プロセスが数分以上CPUの99%を継続的に消費している場合に識別できます。

apache2プロセスでstrace- ppidを実行したところ、次のシステムコールが継続的に繰り返されていることがわかりました。

sendto(25, "Q\0\0\0SSELECT (1) AS \"a\" FROM \"account_profile\" WHERE \"account_profile\".\"id\" = 66201 \0", 84, 0, NULL, 0) = 84
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
poll([{fd=25, events=POLLIN|POLLERR, revents=POLLIN}], 1, -1) = 1
recvfrom(25, "E\0\0\0\210SERROR\0C25P02\0Mcurrent transaction is aborted, commands ignored until end of transaction block\0Fpostgres.c\0L906\0Rexec_simple_query\0\0Z\0\0\0\5E", 16384, 0, NULL, NULL) = 143

この正確なフラグメントはトレース内で継続的に繰り返され、最終的にapache2プロセスを強制終了する前に10分以上実行されていました。(注:これを編集して、以前のstraceフラグメントを、切り捨てられるのではなく、文字列の内容全体を表示する新しいフラグメントに置き換えました。)

上記の私の解釈は、djangoが私のテーブルaccount_profileで存在チェックを行おうとしているということですが、ある初期の時点(トレースを開始する前)で何かがうまくいきませんでした(SQL解析エラー?参照整合性または一意性制約違反?誰が知っていますか? )、そして今Postgresqlはエラー「現在のトランザクションは中止されました」を返しています。何らかの理由で、例外を発生させてあきらめる代わりに、再試行を続けます。

1つの可能性は、これがProfile.objects.get_or_createの呼び出しでトリガーされていることです。これは、account_profileテーブルにマップするモデルクラスです。おそらく、get_or_createに、広すぎる例外のセットをキャッチして再試行するように設計されたものがありますか?Webサーバーのログから、このライブロックは、サイトの登録フォームのPOSTボタンをダブルクリックした結果として発生した可能性があるようです。

この状態は、ライブサイトで過去数日間に数回発生し、介入するまで大幅に遅くなるため、無限のデッドロック以外のほとんどの問題が改善されます。:)

4

2 に答える 2

1

これは完全に私のせいであることが判明しました。select (1) as 'a'ステートメントが(で)発生しているように見える場所を見つけ、django/models/base.pyそれをハッキングしてトレースバックをログに記録しました。これは、私のコードを明確に示しています。

プロファイルごとに一意の電子メール「キー」を構成するコードがいくつかありました。これらのキーはランダムに生成されるため、重複する可能性があるため、whileループ内でtry/exceptで実行します。私の想定では、キーが一意でない場合、データベースの一意の制約により保存が失敗し、再試行できます。

残念ながら、Postgresqlでは、整合性エラーの後で単純に再試行することはできません。再試行する前に、COMMITまたはROLLBACKコマンドを発行する必要があります(自動コミットモードの場合でも、明らかに)。そのため、エラーメッセージを無視して、保存の試行が失敗するという無限ループが発生しました。

ここで、より具体的な例外()を探しdjango.db.IntegrityError、ループが無限にならないように、限られた回数の試行を実行します。

閲覧/回答してくださった皆様、ありがとうございました。

于 2010-01-08T15:07:55.017 に答える
-1

あなたの分析はかなり良さそうです。明らかに、トランザクションが中止されたという事実を認識していません。これをバグとして django プロジェクトに報告することをお勧めします...

于 2010-01-06T17:54:32.157 に答える