アイドル状態のPostgreSQL接続にタイムアウトはありますか?


94
1 S postgres  5038   876  0  80   0 - 11962 sk_wai 09:57 ?        00:00:00 postgres: postgres my_app ::1(45035) idle                                                                                 
1 S postgres  9796   876  0  80   0 - 11964 sk_wai 11:01 ?        00:00:00 postgres: postgres my_app ::1(43084) idle             

たくさん見かけます。接続リークを修正しようとしています。しかし、その間、これらのアイドル接続のタイムアウトを設定する必要があります。


どのようにDBに接続していますか?socketTimeoutは、あなたが探しているものかもしれません。
Doon

私たちはこのレガシーPylons Webアプリを持っており、SQLAlchemyを使用しましたが、明らかにそれを適切に使用していません。覚えていません。リークを修正しようとしています。socketTimeoutドキュメントからは、DBへの接続を完全に閉じるように見えます。各アイドルをクローズしようとしていますが、接続が確立するとすぐにカウンターが開始します。
user1012451


@ user1012451「アイドルを閉じる」と言った場合<IDLE> in transaction、セッションを終了して、セッションを実行したままの<IDLE>状態にしますか?つまり、トランザクションは終了しますが、セッションは終了しませんか?(反対投票:不明な質問)
クレイグリンガー、

@CraigRingerしばらくすると、最大クライアント接続に達します。これを解決するには、webappを再起動する必要があります。これにより、postgresqlも強制的に再起動されます。それはすべての接続を一掃します。これらがidle永遠に見られるときは、各接続/セッションにタイムアウトを設定できるかどうかを尋ねています(正直なところ、正しい用語がわかりません)。トランザクションは、通常のWebアプリケーションのために5分かかる場合何かが間違っている必要があります....
user1012451

回答:


118

プールされた接続を閉じることができないため、アプリケーションで接続リークが発生しているようです。セッションだけでなく、全体的に接続が多すぎるという問題はありません。<idle> in transaction

接続を殺すことはそのための正しい答えではありませんが、それはOKっぽい一時的な回避策です。

他のすべての接続をPostgreSQLデータベースからブートするためにPostgreSQLを再起動するのではなく、他のすべてのユーザーをpostgresデータベースからデタッチする方法を参照してくださいそしてそれへのアクティブな接続がある場合、どのようにPostgreSQLデータベースをドロップするには?。後者はより良いクエリを示しています。

タイムアウトの設定については、@ Doonが提案したように、PostgreSQLのアイドル接続を自動的に閉じる方法を参照してくださいPgBouncerを使用してPostgreSQLのプロキシを作成し、アイドル接続を管理することをお勧めします。とにかく接続をリークするバグのあるアプリケーションがある場合、これは非常に良いアイデアです。私は非常に強く PgBouncerの設定をお勧めします。

TCPキープアライブはアプリがまだ接続して生きているので、それだけではありません、ここで仕事をしません。

PostgreSQL 9.2以降では、新しいstate_changeタイムスタンプ列とstateフィールドを使用pg_stat_activityして、アイドル接続リーパーを実装できます。cronジョブで次のように実行します。

SELECT pg_terminate_backend(pid)
    FROM pg_stat_activity
    WHERE datname = 'regress'
      AND pid <> pg_backend_pid()
      AND state = 'idle'
      AND state_change < current_timestamp - INTERVAL '5' MINUTE;

古いバージョンでは、接続がアイドルになったときを追跡する複雑なスキームを実装する必要があります。邪魔しないで; pgbouncerを使用してください。


4
良いですが、他のPgAdminバックエンドを強制終了します。追加の条件application_name = ''を使用
Andrew Selivanov '19 / 04/13

1
pgbouncerを使用している場合、pg_terminate_backendを実行できますか?
Henley Chiu

@HenleyChiu特に確認していませんが、なぜかわかりません。
クレイグリンガー

1
これを実行すると、私のWAL送信者プロセスが終了したようです
Joseph Persie

@CraigRingerは、psql接続であってもアイドル接続と見なされます。そして、なぜ最初にアイドル接続を閉じる必要があるのですか?私はpgとの接続を確立する長い実行中のコードがいくつかのdml操作を実行してから、キュー上のメッセージを待機してから、さらにいくつかのdml操作を実行します。それでも郵便局との接続はidleです。なぜ閉じなければならないのですか。
Viren

72

PostgreSQL 9.6には、idle_in_transaction_session_timeoutあなたが説明したことを実現する新しいオプションがあります。SET次のコマンドを使用して設定できます。

SET SESSION idle_in_transaction_session_timeout = '5min';

1
それはとても単純なことを尋ねる必要はありませんが、私はデータベース一般にはまったく新しいです-この機能の使用方法の非常に基本的な例を教えていただけませんか?
sg 2017年

以前のバージョンのPostgreSQLでこのようなものは何ですか?
sdsc81 2017

いいえ、以前のバージョンでは他の回答と同様のものが必要です。
shosti 2017

データベースを再起動するたびにこのパラメータを設定する必要がありますか?または、一度行った後で忘れることはできますか?ありがとう
fresko 2018年

5
SET SESSION現在のセッション用です(新しい接続を開くと、デフォルトに戻ります)。またALTER DATABASE SET idle_in_transaction_session_timeout = '5min'、たとえば、または構成ファイルを使用して、データベースレベルで構成パラメーターを設定することもできます(postgresql.org/docs/current/static/config-setting.htmlを参照)。
shosti 2018年

22

PostgreSQL 9.1では、次のクエリによるアイドル接続。データベースの再起動に必要な状況を回避するのに役立ちました。これは主に、JDBC接続が開かれていて適切に閉じられていない場合に発生します。

SELECT
   pg_terminate_backend(procpid)
FROM
   pg_stat_activity
WHERE
   current_query = '<IDLE>'
AND
   now() - query_start > '00:10:00';

1
pg_terminate_backendは8.4以降にあります
Andrew Banks


0

外部のスケジュールされたタスクなしでデータベースセッションタイムアウトを有効にできる可能な回避策は、私が開発した拡張機能pg_timeoutを使用することです。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.