web-dev-qa-db-fra.com

Y a-t-il un délai d'attente pour les connexions PostgreSQL inactives?

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.

76
user1012451

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.

102
Craig Ringer

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';
54
shosti

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';
19
sramay

si vous utilisez postgresql 9.6+, vous pouvez définir dans votre postgresql.conf

idle_in_transaction_session_timeout = 30000(msec)

4
Bertrand David