For dem, der er interesseret, er her den løsning, jeg fandt på, inspireret af Craig Ringers kommentar:
(...) brug et cron-job til at se, hvornår forbindelsen sidst var aktiv (se pg_stat_activity), og brug pg_terminate_backend til at dræbe gamle.(...)
Den valgte løsning kommer således ud:
- Først opgraderer vi til Postgresql 9.2.
- Derefter planlægger vi en tråd til at køre hvert sekund.
- Når tråden kører, leder den efter gamle inaktive forbindelser.
- En forbindelse betragtes som inaktiv hvis dens tilstand er enten
idle
,idle in transaction
,idle in transaction (aborted)
ellerdisabled
. - En forbindelse anses for at være gammel hvis dens tilstand forblev den samme i mere end 5 minutter.
- En forbindelse betragtes som inaktiv hvis dens tilstand er enten
- Der er yderligere tråde, der gør det samme som ovenfor. Disse tråde forbinder dog til databasen med en anden bruger.
- Vi lader mindst én forbindelse stå åben for enhver applikation, der er forbundet til vores database. (
rank()
funktion)
Dette er SQL-forespørgslen, der køres af tråden:
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