Det lyder som om du har en forbindelseslækage i din applikation, fordi den ikke lukker poolede forbindelser . Du har ikke kun problemer med <idle> in transaction
sessioner, men med alt for mange forbindelser.
At dræbe forbindelser er ikke det rigtige svar på det, men det er en OK-ish midlertidig løsning.
I stedet for at genstarte PostgreSQL for at starte alle andre forbindelser fra en PostgreSQL-database, se:Hvordan frigør jeg alle andre brugere fra en postgres-database? og Hvordan dropper man en PostgreSQL-database, hvis der er aktive forbindelser til den? . Sidstnævnte viser en bedre forespørgsel.
For at indstille timeouts, som @Doon foreslog, se Hvordan lukker man inaktive forbindelser i PostgreSQL automatisk?, som råder dig til at bruge PgBouncer til at proxy for PostgreSQL og administrere inaktive forbindelser. Dette er en meget god idé, hvis du har en buggy-applikation, der alligevel lækker forbindelser; Jeg meget stærkt anbefaler at konfigurere PgBouncer.
En TCP Keepalive vil ikke klare opgaven her, fordi appen stadig er tilsluttet og i live, det burde den bare ikke være.
I PostgreSQL 9.2 og nyere kan du bruge den nye state_change
tidsstempelkolonnen og state
felt for pg_stat_activity
at implementere en ledig forbindelsesreaper. Få et cron-job til at køre noget som dette:
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;
I ældre versioner skal du implementere komplicerede skemaer, der holder styr på, hvornår forbindelsen gik inaktiv. Tag dig ikke af det; bare brug pgbouncer.