Pour ceux que ça intéresse, voici la solution que j'ai trouvée, inspirée du commentaire de Craig Ringer :
(...) utilisez une tâche cron pour voir quand la connexion a été active pour la dernière fois (voir pg_stat_activity) et utilisez pg_terminate_backend pour tuer les anciennes.(...)
La solution choisie se résume ainsi :
- Tout d'abord, nous effectuons une mise à niveau vers Postgresql 9.2.
- Ensuite, nous planifions l'exécution d'un thread toutes les secondes.
- Lorsque le thread s'exécute, il recherche les anciennes connexions inactives.
- 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 ancienne si son état resté le même pendant plus de 5 minutes.
- Une connexion est considérée comme inactive si son état est soit
- Il existe des threads supplémentaires qui font la même chose que ci-dessus. Cependant, ces threads se connectent à la base de données avec un utilisateur différent.
- Nous laissons au moins une connexion ouverte pour toute application connectée à notre base de données. (
rank()
fonction)
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