一部のクライアントはpostgresqlデータベースに接続しますが、接続は開いたままにします。一定量の非アクティブ後にPostgresqlにこれらの接続を閉じるように指示することは可能ですか?
TL; DR
Postgresqlバージョンを使用している場合> =
9.2
THENを使用 私が思いついた解決策コードを書きたくない場合
THENを使用 arqnidの解
興味のある方のために、 Craig Ringer のコメントに触発された、私が思いついた解決策を以下に示します。
(...)cronジョブを使用して、接続が最後にアクティブになった時間を調べ(pg_stat_activityを参照)、pg_terminate_backendを使用して古い接続を削除します。(...)
選択したソリューションは次のようになります。
- 接続は、そのstateが
idle
、idle in transaction
、idle in transaction (aborted)
またはdisabled
のいずれかである場合、 inactive と見なされます。- 接続は、stateが5分以上同じままであった場合、 old と見なされます。
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
PgBouncer のようなプロキシを介して接続します。これにより、server_idle_timeout
秒。
9.6以上のPostgreSQLを使用している場合、さらに簡単な解決策があります。 5分ごとにすべてのアイドル状態の接続を削除する場合、次のコマンドを実行するだけです。
alter system set idle_in_transaction_session_timeout='5min';
スーパーユーザーとしてアクセスできない場合(Azureクラウドの例)、試してください:
SET SESSION idle_in_transaction_session_timeout = '5min';
ただし、後者は現在のセッションでのみ機能しますが、ほとんどの場合、これは望みのものではありません。
無効化機能
alter system set idle_in_transaction_session_timeout=0;
または
SET SESSION idle_in_transaction_session_timeout = 0;
(ところで、0はデフォルト値です)。
alter system
を使用する場合、構成をリロードして変更を開始する必要があり、変更は永続的です。たとえば、サーバーを再起動する場合、クエリを再実行する必要はありません。
機能の状態を確認するには:
show idle_in_transaction_session_timeout;