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分)。
プールされた接続を閉じることができないであるため、アプリケーションに接続リークがあるように聞こえます。 <idle> in transaction
セッションだけで問題が発生しているのではなく、全体的に接続が多すぎます。
接続を強制終了することはそのための正しい答えではありませんが、それは問題のない一時的な回避策です。
PostgreSQLを再起動してPostgreSQLデータベースから他のすべての接続を起動するのではなく、次を参照してください: 他のすべてのユーザーをpostgresデータベースから切り離すにはどうすればよいですか? および PostgreSQLデータベースへのアクティブな接続がある場合、PostgreSQLデータベースを削除する方法は? 後者はより良いクエリを示しています。
@Doonが提案したタイムアウトの設定については、 PostgreSQLのアイドル接続を自動的に閉じる方法を参照してください? 、PgBouncerを使用してPostgreSQLをプロキシし、アイドル接続を管理することをお勧めします。とにかく接続をリークするバグのあるアプリケーションがある場合、これは非常に良い考えです。 I 非常に強く PgBouncerの設定を推奨します。
TCPキープアライブ は、アプリがまだ接続されて生きているので、ここでは仕事をしません。
PostgreSQL 9.2以降では、新しいstate_change
タイムスタンプ列とpg_stat_activity
のstate
フィールドを使用して、アイドル接続リーパーを実装できます。 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を使用してください。
PostgreSQL 9.6には、新しいオプション idle_in_transaction_session_timeout
があり、これはあなたが説明したことを達成するはずです。 SET
コマンドを使用して設定できます。例:
SET SESSION idle_in_transaction_session_timeout = '5min';
PostgreSQL 9.1では、次のクエリによるアイドル接続。データベースの再起動を保証する状況を避けるのに役立ちました。これは、JDBC接続が適切に開かれ、閉じられていない場合に発生します。
SELECT
pg_terminate_backend(procpid)
FROM
pg_stat_activity
WHERE
current_query = '<IDLE>'
AND
now() - query_start > '00:10:00';
postgresql 9.6+を使用している場合、postgresql.confで設定できます
idle_in_transaction_session_timeout = 30000
(msec)