17

アプリケーションの 1 つに Postgres を使用していますが、(それほど頻繁ではありませんが) 接続の 1 つが<IDLE> in transaction状態になり、取得したロックが保持され、他の接続がこれらのロックで待機し、最終的にアプリケーションがハングします。

pg_stat_activity以下は、そのプロセスの表からの出力です。

select * from pg_stat_activity

24081 | db     |     798 |    16384 | db     |                  | 10.112.61.218 |                 |       59034 | 2013-09-12 23:46:05.132267+00 | 2013-09-12 23:47:31.763084+00 | 2013-09-12 23:47:31.763534+00 | f       | <IDLE> in transaction

PID=798状態であることを示します<IDLE> in transaction。Web サーバー上のクライアント プロセスは、上記の出力のclient_port( ) を使用して次のように検出されます。59034

sudo netstat -apl | grep 59034

tcp        0      0 ip-10-112-61-218.:59034 db-server:postgresql    ESTABLISHED 23843/pgbouncer

接続がハングする原因となっているアプリケーション コード (実行中のアプリケーション cron の 1 つを強制終了し、ロックを解放した) に何か問題があることはわかっていますが、それを追跡することはできません。

これはあまり頻繁ではなく、本番サーバーでのみ発生するため、明確な再現手順も見つかりません。

このようなアイドル状態の接続をトレースする方法についての入力を取得したいと思います。たとえば、最後に実行されたクエリを取得したり、コードのどの部分がこの問題を引き起こしているかを特定するために何らかのトレースバックを取得したりします。

4

1 に答える 1

12

9.2 以降にアップグレードすると、接続pg_stat_activityに対して実行された最新のクエリがビューに表示されidle in transactionます。

select * from pg_stat_activity  \x\g\x

...
waiting          | f
state            | idle in transaction
query            | select count(*) from pg_class ;

(9.1 でも)プロセスpg_locksによって保持されているロックを確認することもできidle in transactionます。非常に一般的に使用されるオブジェクトにのみロックがある場合、これは物事をあまり絞り込まないかもしれませんが、コード内のどこを見ればよいかを正確に伝えることができる独特のロックである場合.

9.1 に行き詰まっている場合は、おそらくデバッガーを使用して、クエリの最初の 22 文字を除くすべての文字を取得できます (最初の 22 文字は<IDLE> in transaction\0メッセージによって上書きされます)。例えば:

(gdb) printf "%s\n", ((MyBEEntry->st_activity)+22)
于 2013-09-13T18:12:35.023 に答える