ERREUR PostgreSQL: plus de connexions autorisées


19

Comment libérer des connexions PostgreSQL qui ne sont pas correctement fermées par les applications clientes?

J'ai une application d'exploration de données qui fait tourner plusieurs processus, toute connexion à une base de données PostgreSQL 9.1 locale pour récupérer des données. Il fonctionne bien pendant quelques heures, mais meurt ensuite avec l'erreur:

FATAL:  remaining connection slots are reserved for non-replication superuser connections

Les recherches montrent que cela est probablement dû au fait que l'application ne ferme pas correctement ses connexions. Cependant, même avec l'application supprimée, ces connexions ne sont jamais libérées. N'y a-t-il pas une sorte de délai d'expiration où PostgreSQL ferme automatiquement une connexion?

J'ai également essayé d'augmenter le nombre max_connections de Postgres de 100 à 200, mais le redémarrage m'a donné l'erreur:

2014-02-23 10:51:15 EST FATAL:  could not create shared memory segment: Invalid argument
2014-02-23 10:51:15 EST DETAIL:  Failed system call was shmget(key=5432001, size=36954112, 03600).
2014-02-23 10:51:15 EST HINT:  This error usually means that PostgreSQL's request for a shared memory segment exceeded your kernel's SHMMAX parameter.  You can either reduce the request size or reconfigure the kernel with larger SHMMAX.  To reduce the request size (currently 36954112 bytes), reduce PostgreSQL's shared memory usage, perhaps by reducing shared_buffers or max_connections.
    If the request size is already small, it's possible that it is less than your kernel's SHMMIN parameter, in which case raising the request size or reconfiguring SHMMIN is called for.
    The PostgreSQL documentation contains more information about shared memory configuration.

Mon système est Ubuntu 12.04 et dispose de 8 Go de mémoire, et tous les autres paramètres PG sont par défaut, donc je ne sais pas pourquoi il pense que le système n'a pas assez de mémoire.

J'ai ensuite essayé d'utiliser pgbouncer pour regrouper et réutiliser les connexions. Cela semble fonctionner un peu mieux, mais même cela finit par manquer de connexions, ce qui me donne l'erreur:

ERROR:  no more connections allowed

Comment puis-je diagnostiquer et résoudre ce problème?


Afficher la sortie de pg_stat_activity
ETL

Réponses:


8

Vous pouvez augmenter le nombre maximal de connexions en modifiant vos paramètres de mémoire partagée maximale, mais si le problème est que vos connexions ne sont pas fermées, vous devez vraiment résoudre ce problème. Si le logiciel est hors de votre contrôle et est bogué en ne fermant pas les connexions, vous pouvez utiliser des tâches cron comme:

select pg_terminate_backend(procpid)
from pg_stat_activity
where usename = 'yourusername'
 and current_query = '<IDLE>'
 and query_start < current_timestamp - interval '5 minutes'
;

C'est ce que je fais pour tuer les connexions qui fuient à partir d'un logiciel de buggy similaire.

Alternativement, vous pourrez peut-être exécuter votre logiciel de buggy via un pool de connexions qui a une fonctionnalité similaire pour tuer les connexions inactives telles que pgpool.

Remarque : les nouvelles versions de Postgres ont des noms de colonnes légèrement différents:

select pg_terminate_backend(pid)
from pg_stat_activity
where usename = 'YOURDATABASEUSERNAME*'
 and state = 'idle'
 and query_start < current_timestamp - interval '5 minutes'
;

Cela devrait-il fonctionner sur 9.6? Quand j'essaye, je reçoispostgres=> select pg_terminate_backend(procpid) from pg_stat_activity where current_query = '<IDLE>' and query_start < current_timestamp - interval '5 minutes'; ERROR: column "procpid" does not exist LINE 1: select pg_terminate_backend(procpid) from pg_stat_activity ...
Magick

C'est au pidlieu de procpiddans les versions plus récentes.
ETL

4

Pour les nouvelles versions de PostgreSQL:

select pg_terminate_backend(pid)
from pg_stat_activity
where usename = 'YOUR_DATABASE_USERNAME*'
 and state = 'idle'
 and query_start < current_timestamp - interval '5 minutes'
;

Ce qui précède vous aidera à mettre fin à vos connexions inactives. J'ai eu le même problème, mais cela s'est avéré être un problème avec ma façon Flask et SQLAlchemy de se connecter à la base de données.

* le nom d' utilisateur n'est pas une faute de frappe


En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.