128 votes

Existe-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 en attendant, nous voulons définir un délai d'attente pour ces connexions inactives, peut-être de 5 minutes maximum.

151voto

Craig Ringer Points 72371

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.

86voto

shosti Points 4672

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 fonction SET commande, par exemple :

SET SESSION idle_in_transaction_session_timeout = '5min';

23voto

sramay Points 41

Dans PostgreSQL 9.1, les connexions inactives avec la requête suivante. Elle m'a permis de parer à la situation qui justifiait le redémarrage de la base de données. Cela se produit principalement avec les 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';

13voto

Bertrand David Points 31

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

idle_in_transaction_session_timeout = 30000 (msec)

6voto

rustyx Points 2722

Il existe un délai d'attente pour les connexions interrompues (c'est-à-dire dues à des erreurs réseau), qui repose sur la fonction TCP keepalive du système d'exploitation. Par défaut sous Linux, les connexions TCP interrompues sont fermées après ~2 heures (cf. sysctl net.ipv4.tcp_keepalive_time ).

Il existe également un délai d'attente pour les transactions abandonnées, idle_in_transaction_session_timeout et sur les serrures, lock_timeout . Il est recommandé de les définir dans postgresql.conf .

Mais il n'y a pas de délai d'attente pour une connexion client correctement établie. Si un client veut garder la connexion ouverte, il devrait pouvoir le faire indéfiniment. Si un client laisse fuir des connexions (comme ouvrir de plus en plus de connexions sans jamais les fermer), alors réparez le client. Faites no essayer d'interrompre les connexions inactives correctement établies du côté du serveur.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X