Sembra che tu abbia un file perdita di connessione nella tua applicazione perché non riesce a chiudere le connessioni in pool . Non hai problemi solo con le <idle> in transaction
sessioni, ma con troppe connessioni in generale.
Eliminare le connessioni non è la risposta giusta per questo, ma è una soluzione temporanea accettabile.
Invece di riavviare PostgreSQL per avviare tutte le altre connessioni da un database PostgreSQL, vedere: Come posso scollegare tutti gli altri utenti da un database postgres? e come eliminare un database PostgreSQL se ci sono connessioni attive ad esso? . Quest'ultimo mostra una query migliore.
Per impostare i timeout, come suggerito da @Doon, vedere Come chiudere automaticamente le connessioni inattive in PostgreSQL? , che consiglia di utilizzare PgBouncer per eseguire il proxy per PostgreSQL e gestire le connessioni inattive. Questa è un'ottima idea se hai un'applicazione difettosa che perde comunque le connessioni; Consiglio vivamente di configurare PgBouncer.
UN keepalive TCP non farà il lavoro qui, perché l'app è ancora connessa e attiva, semplicemente non dovrebbe esserlo.
In PostgreSQL 9.2 e versioni successive, è possibile utilizzare la nuova state_change
colonna timestamp e il state
campo di pg_stat_activity
per implementare un mietitore di connessione inattivo. Fai eseguire a un cron job qualcosa del genere:
SELECT pg_terminate_backend(pid)
FROM pg_stat_activity
WHERE datname = 'regress'
AND pid <> pg_backend_pid()
AND state = 'idle'
AND state_change < current_timestamp - INTERVAL '5' MINUTE;
Nelle versioni precedenti è necessario implementare schemi complicati che tengano traccia di quando la connessione è diventata inattiva. Non si disturbi; basta usare pgbouncer.