Para aquellos que estén interesados, aquí está la solución que se me ocurrió, inspirado en Craig Ringer 's comentario:
(...) utilizar una tarea programada para mirar cuando la conexión fue el último activa (ver pg_stat_activity) y utilizar pg_terminate_backend para matar a los viejos (...)
La solución elegida se reduce de esta manera:.
- Primero, actualizamos a Postgresql 9.2.
- Luego, programamos un hilo para que se ejecute cada segundo.
- Cuando se ejecuta el subproceso, busca cualquier conexión inactiva anterior.
- Una conexión se considera inactivo si su estado es o bien
idle
, idle in transaction
, idle in transaction (aborted)
o disabled
.
- Se considera que una conexión es anterior si su último estado ha cambiado durante más de 5 minutos.
- Hay subprocesos adicionales que hacen lo mismo que el anterior. Sin embargo, esos hilos se conectan a la base de datos con diferentes usuarios.
- Dejamos al menos una conexión abierta para cualquier aplicación conectada a nuestra base de datos. (
rank()
función)
Ésta es la consulta SQL a cargo de la rosca:
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
Se podría utilizar una tarea programada para mirar cuando la conexión estuvo activo (véase 'pg_stat_activity') y el uso de' pg_terminate_backend' para matar a los viejos. Expresado fácilmente en una consulta simple. Sin embargo, no estoy seguro de si 'pg_terminate_backend' estaba disponible en el bonito y antiguo 8.3. –