Sembra che tu abbia una perdita di connessione nell'applicazione perché non riesce a chiudere le connessioni in pool . Non stai riscontrando problemi solo con <idle> in transaction
sessioni, ma con troppe connessioni in generale.
Uccidere 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 si scollegano 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 si dispone di un'applicazione difettosa che perde comunque le connessioni; Io molto forte consiglio di configurare PgBouncer.
Un keep-alive TCP non farà il lavoro qui, perché l'app è ancora connessa e attiva, semplicemente non dovrebbe esserlo.
In PostgreSQL 9.2 e versioni successive, puoi utilizzare il nuovo state_change
colonna timestamp e lo state
campo di pg_stat_activity
per implementare un reaper di connessione inattivo. Fai in modo che un processo cron esegua 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 è andata inattiva. Non si disturbi; usa semplicemente pgbouncer.