1 S postgres 5038 876 0 80 0 - 11962 sk_wai 09:57 ? 00:00:00 postgres: postgres my_app ::1(45035) idle
1 S postgres 9796 876 0 80 0 - 11964 sk_wai 11:01 ? 00:00:00 postgres: postgres my_app ::1(43084) idle
J'en vois beaucoup. Nous essayons de réparer notre fuite de connexion. Mais pendant ce temps, nous voulons définir un délai d’attente pour ces connexions inactives, pouvant aller jusqu’à 5 minutes.
On dirait que vous avez une fuite de connexion dans votre application car elle ne ferme pas les connexions en pool . Vous n'avez pas de problèmes uniquement avec <idle> in transaction
sessions, mais avec trop de connexions globales.
Tuer des connexions n’est pas la bonne solution, mais c’est une solution de contournement 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 puis-je détacher tous les autres utilisateurs d'une base de données Postgres? et Comment supprimer une base de données PostgreSQL si y a-t-il des connexions actives? . Ce dernier montre une meilleure requête.
Pour la définition des délais, comme suggéré par @Doon, voir Comment fermer automatiquement les connexions inactives dans PostgreSQL? , qui vous conseille d'utiliser PgBouncer comme proxy pour PostgreSQL et de gérer les connexions inactives. Ceci est une très bonne idée si vous avez une application buggy qui fuit les connexions quand même; Je recommande fortement de configurer PgBouncer .
Un TCP keepalive 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 supérieur, vous pouvez utiliser le nouveau state_change
_ Colonne d'horodatage et le champ state
de pg_stat_activity
pour implémenter une connexion de connexion inactive. Avoir un travail cron exécuter quelque chose comme ça:
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 implémenter des schémas complexes qui permettent de savoir quand la connexion est devenue inactive. Ne pas déranger; utilisez simplement pgbouncer.
Dans PostgreSQL 9.6, il y a une nouvelle option idle_in_transaction_session_timeout
qui devrait accomplir ce que vous décrivez. Vous pouvez le définir en utilisant la commande SET
, par exemple:
SET SESSION idle_in_transaction_session_timeout = '5min';
Dans PostgreSQL 9.1, les connexions inactives avec la requête suivante. Cela m'a aidé à conjurer la situation qui justifiait le redémarrage de la base de données. Cela se produit principalement avec des connexions JDBC ouvertes et non fermées correctement.
SELECT
pg_terminate_backend(procpid)
FROM
pg_stat_activity
WHERE
current_query = '<IDLE>'
AND
now() - query_start > '00:10:00';
si vous utilisez postgresql 9.6+, vous pouvez définir dans votre postgresql.conf
idle_in_transaction_session_timeout = 30000
(msec)