Certains clients se connectent à notre base de données postgresql mais laissent les connexions ouvertes .. Est-il possible de dire à Postgresql de fermer ces connexions après un certain temps d'inactivité?
TL; DR
SI vous utilisez une version Postgresql> =
9.2
ALORS utiliser la solution que j'ai proposéeSI vous ne voulez pas écrire de code
ALORS utiliser la solution d’arqnid
Pour ceux qui sont intéressés, voici la solution que j'ai proposée, inspirée du commentaire de Craig Ringer :
(...) utilise un travail cron à regarder quand la connexion a été active pour la dernière fois (voir pg_stat_activity) et utilise pg_terminate_backend pour tuer les anciens. (...) _
La solution choisie se présente comme ceci:
- Une connexion est considérée comme inactive si son état est soit
idle
,idle in transaction
,idle in transaction (aborted)
oudisabled
.- Une connexion est considérée comme old si son état est resté le même pendant plus de 5 minutes.
rank()
)Voici la requête SQL exécutée par le thread:
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
Connectez-vous via un proxy comme PgBouncer qui fermera les connexions après server_idle_timeout
secondes.
Si vous utilisez PostgreSQL> = 9.6, la solution est encore plus simple. Supposons que vous souhaitiez supprimer toutes les connexions inactives toutes les 5 minutes, exécutez ce qui suit:
alter system set idle_in_transaction_session_timeout='5min';
Si vous n'avez pas accès en tant que superutilisateur (exemple sur le cloud Azure), essayez:
SET SESSION idle_in_transaction_session_timeout = '5min';
Mais ce dernier ne fonctionnera que pour la session en cours, ce n'est probablement pas ce que vous voulez.
Pour désactiver la fonctionnalité,
alter system set idle_in_transaction_session_timeout=0;
ou
SET SESSION idle_in_transaction_session_timeout = 0;
(au fait, 0 est la valeur par défaut).
Si vous utilisez alter system
, vous devez recharger la configuration pour commencer la modification et la modification est persistante. Vous n'avez plus à réexécuter la requête si, par exemple, vous redémarrez le serveur.
Pour vérifier l'état de la fonctionnalité:
show idle_in_transaction_session_timeout;