112
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分に設定する必要があります。

4

7 に答える 7

135

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

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

PostgreSQLを再起動してPostgreSQLデータベースから他のすべての接続を起動するのではなく、「postgresデータベースから他のすべてのユーザーを切り離すにはどうすればよいですか?」を参照してください。PostgreSQLデータベースへのアクティブな接続がある場合に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を使用するだけです。

于 2012-11-06T05:37:49.790 に答える
81

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

SET SESSION idle_in_transaction_session_timeout = '5min';
于 2017-01-24T01:09:11.220 に答える
23

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

SELECT
   pg_terminate_backend(procpid)
FROM
   pg_stat_activity
WHERE
   current_query = '<IDLE>'
AND
   now() - query_start > '00:10:00';
于 2013-05-16T08:22:01.560 に答える
12

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

idle_in_transaction_session_timeout = 30000 (ミリ秒)

于 2018-03-03T20:58:04.567 に答える
3

OSのTCPキープアライブ機能に依存する、切断された接続(つまり、ネットワークエラーによる)でタイムアウトが発生します。Linuxのデフォルトでは、切断されたTCP接続は約2時間後に閉じられます(を参照sysctl net.ipv4.tcp_keepalive_time)。

放棄されたトランザクションidle_in_transaction_session_timeoutとロックにもタイムアウトがありlock_timeoutます。これらをに設定することをお勧めしpostgresql.confます。

ただし、適切に確立されたクライアント接続のタイムアウトはありません。クライアントが接続を開いたままにしておきたい場合は、無期限に接続できるはずです。クライアントが接続をリークしている場合(接続を増やして閉じないなど)、クライアントを修正します。サーバー側で適切に確立されたアイドル接続を中止しようとしないでください。

于 2021-01-06T12:21:46.230 に答える
1

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

于 2020-04-05T11:32:40.807 に答える
1

別のオプションとして、この値「tcp_keepalives_idle」を設定します。詳細については、ドキュメントhttps://www.postgresql.org/docs/10/runtime-config-connection.htmlをご覧ください。

于 2020-12-14T12:11:52.510 に答える