On dirait que vous avez un fuite de connexion dans votre application car il ne parvient pas à fermer les connexions groupées . Vous n'avez pas seulement des problèmes avec <idle> in transaction
mais avec trop de connexions dans l'ensemble.
Tuer les connexions n'est pas la bonne solution, mais c'est une solution temporaire acceptable.
Plutôt que de redémarrer PostgreSQL pour amorcer toutes les autres connexions à partir d'une base de données PostgreSQL, voir : Comment détacher tous les autres utilisateurs d'une base de données postgres ? y Comment supprimer une base de données PostgreSQL si des connexions y sont actives ? . Ce dernier montre une meilleure requête.
Pour définir les délais, comme @Doon l'a suggéré, voir Comment fermer automatiquement les connexions inactives dans PostgreSQL ? qui vous conseille d'utiliser PgBouncer comme proxy pour PostgreSQL et pour gérer les connexions inactives. C'est une très bonne idée si vous avez une application boguée qui fait fuir les connexions de toute façon. très fortement recommande de configurer PgBouncer.
A TCP keepalive ne fera pas l'affaire ici, car l'application est toujours connectée et vivante, mais elle ne devrait pas l'être.
Dans PostgreSQL 9.2 et plus, vous pouvez utiliser la nouvelle fonction state_change
et la colonne de l'horodatage state
domaine de pg_stat_activity
pour mettre en œuvre un faucheur de connexions inactives. Faites en sorte qu'un travail cron exécute quelque chose comme ceci :
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;
Dans les versions plus anciennes, vous devez mettre en place des mécanismes compliqués pour savoir quand la connexion est inactive. Ne vous inquiétez pas, utilisez simplement pgbouncer.