1. ホーム
  2. postgresql

PostgreSQLでアイドル状態の接続を自動的にクローズする方法は?

2023-10-10 09:05:51

質問

一部のクライアントは、私たちの postgresql データベースに接続しますが、接続を開いたままにしています。 一定時間操作がないと接続を閉じるよう、Postgresqlに指示することは可能でしょうか?

TL;DR

<ブロッククオート

Postgresqlのバージョン >= を使っている場合。 9.2

次に 私が思いついた解決策

コードを書きたくない場合

ということであれば arqnidの解決策

コードを書きたくない場合

そして、あなたはPostgresqlのバージョンを使用している >= 。 14

次に Laurenz Albe の解決策

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

興味のある方のために、以下は私が思いついた解決策です。 クレイグ・リンガー のコメントに触発されたものです。

(...) cronジョブを使用して、接続が最後にアクティブになった時刻を調べ(pg_stat_activityを参照)、pg_terminate_backendを使用して古いものを削除します(...)

選択された解決策は以下のようになります。

  • まず、Postgresql 9.2 にアップグレードします。
  • 次に、1秒ごとに実行するスレッドをスケジュールします。
  • スレッドが実行されると、古い非アクティブな接続がないかどうかを調べます。
    • 接続があるとみなされるのは 非アクティブ もしその 状態 idle , idle in transaction , idle in transaction (aborted) または disabled .
    • 接続を考慮する 古い もしその 状態 が5分以上同じであった場合。
  • 上記と同じことをするスレッドが追加で存在します。ただし、これらのスレッドは異なるユーザーでデータベースに接続します。
  • データベースに接続するすべてのアプリケーションに対して、少なくとも1つの接続を開いたままにしておきます。( rank() 関数)

これはスレッドによって実行されるSQLクエリです。

WITH inactive_connections AS (
    SELECT
        pid,
        rank() over (partition by client_addr order by backend_start ASC) as rank
    FROM 
        pg_stat_activity
    WHERE
        -- Exclude the thread owned connection (ie no auto-kill)
        pid <> pg_backend_pid( )
    AND
        -- Exclude known applications connections
        application_name !~ '(?:psql)|(?:pgAdmin.+)'
    AND
        -- Include connections to the same database the thread is connected to
        datname = current_database() 
    AND
        -- Include connections using the same thread username connection
        usename = current_user 
    AND
        -- Include inactive connections only
        state in ('idle', 'idle in transaction', 'idle in transaction (aborted)', 'disabled') 
    AND
        -- Include old connections (found with the state_change field)
        current_timestamp - state_change > interval '5 minutes' 
)
SELECT
    pg_terminate_backend(pid)
FROM
    inactive_connections 
WHERE
    rank > 1 -- Leave one connection for each application connected to the database