1. ホーム
  2. postgresql

[解決済み] アイドル状態のPostgreSQL接続にタイムアウトはありますか?

2022-10-30 05:28:10

質問

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             

たくさん見えますね。私たちは、接続の漏れを修正しようとしています。しかし一方で、これらのアイドル接続にタイムアウトを設定したいと思います。

どのように解決するのですか?

それはあなたが持っているように聞こえる 接続漏れ が発生しているようです。 プールされた接続を閉じることができない . という問題だけではありません。 <idle> in transaction セッションの問題ではなく、全体的に接続数が多すぎることが原因です。

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

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

タイムアウトの設定については、@Doon が提案したように PostgreSQL でアイドル状態の接続を自動的に閉じるには? では、PgBouncerを使用してPostgreSQLのプロキシを行い、アイドル状態の接続を管理するように助言しています。これは、とにかく接続が漏れてしまうようなバグだらけのアプリケーションを使用している場合には、非常に良いアイデアです。 非常に強く PgBouncer を構成することをお勧めします。

A 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を使ってください。