Voor degenen die geïnteresseerd zijn, hier is de oplossing die ik bedacht, geïnspireerd op de opmerking van Craig Ringer:
(...) gebruik een cron-job om te kijken wanneer de verbinding voor het laatst actief was (zie pg_stat_activity) en gebruik pg_terminate_backend om oude te verwijderen.(...)
De gekozen oplossing komt er als volgt uit:
- Eerst upgraden we naar Postgresql 9.2.
- Vervolgens plannen we een thread die elke seconde wordt uitgevoerd.
- Als de thread wordt uitgevoerd, zoekt hij naar oude inactieve verbindingen.
- Een verbinding wordt beschouwd als inactief als zijn staat is ofwel
idle
,idle in transaction
,idle in transaction (aborted)
ofdisabled
. - Een verbinding wordt als oud beschouwd als zijn staat bleef meer dan 5 minuten hetzelfde.
- Een verbinding wordt beschouwd als inactief als zijn staat is ofwel
- Er zijn extra threads die hetzelfde doen als hierboven. Deze threads maken echter verbinding met de database met een andere gebruiker.
- We laten ten minste één verbinding open voor elke toepassing die is verbonden met onze database. (
rank()
functie)
Dit is de SQL-query die door de thread wordt uitgevoerd:
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