Il semble que vous ayez une fuite de connexion dans votre application car elle ne parvient pas à fermer les connexions groupées . Vous ne rencontrez pas de problèmes uniquement avec les <idle> in transaction
sessions, mais avec trop de connexions en général.
Tuer les connexions n'est pas la bonne réponse pour cela, mais c'est une solution de contournement temporaire OK.
Plutôt que de redémarrer PostgreSQL pour démarrer toutes les autres connexions à partir d'une base de données PostgreSQL, consultez: Comment détacher tous les autres utilisateurs d'une base de données postgres? et Comment supprimer une base de données PostgreSQL s'il y a des connexions actives? . Ce dernier montre une meilleure requête.
Pour définir les délais d'expiration, comme @Doon l'a suggéré, consultez Comment fermer automatiquement les connexions inactives dans PostgreSQL? , qui vous conseille d'utiliser PgBouncer pour proxy pour PostgreSQL et gérer les connexions inactives. C'est une très bonne idée si vous avez une application boguée qui perd de toute façon des connexions; Je recommande fortement de configurer PgBouncer.
Un keepalive TCP ne fera pas le travail ici, car l'application est toujours connectée et vivante, elle ne devrait tout simplement pas l'être.
Dans PostgreSQL 9.2 et versions ultérieures, vous pouvez utiliser la nouvelle state_change
colonne d'horodatage et le state
champ de pg_stat_activity
pour implémenter un outil de récupération de connexion inactif. Demandez à une tâche cron d'exécuter 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 anciennes versions, vous devez implémenter des schémas complexes qui permettent de suivre le moment où la connexion est devenue inactive. Ne pas déranger; utilisez simplement pgbouncer.