web-dev-qa-db-ja.com

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

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             

たくさん見ます。接続リークを修正しようとしています。ただし、その間、これらのアイドル接続にタイムアウトを設定します(最大5分)。

76
user1012451

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

接続を強制終了することはそのための正しい答えではありませんが、それは問題のない一時的な回避策です。

PostgreSQLを再起動してPostgreSQLデータベースから他のすべての接続を起動するのではなく、次を参照してください: 他のすべてのユーザーをpostgresデータベースから切り離すにはどうすればよいですか? および PostgreSQLデータベースへのアクティブな接続がある場合、PostgreSQLデータベースを削除する方法は? 後者はより良いクエリを示しています。

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

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

PostgreSQL 9.2以降では、新しいstate_changeタイムスタンプ列とpg_stat_activitystateフィールドを使用して、アイドル接続リーパーを実装できます。 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を使用してください。

102
Craig Ringer

PostgreSQL 9.6には、新しいオプション idle_in_transaction_session_timeout があり、これはあなたが説明したことを達成するはずです。 SET コマンドを使用して設定できます。例:

SET SESSION idle_in_transaction_session_timeout = '5min';
54
shosti

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

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

postgresql 9.6+を使用している場合、postgresql.confで設定できます

idle_in_transaction_session_timeout = 30000(msec)

4
Bertrand David