Pourquoi l'erreur « FATAL : remaining connection slots are reserved for non-replicate superuser connections » s’affiche-t-elle lorsque je me connecte à mon Amazon RDS for PostgreSQL alors que je n'ai pas atteint la limite max_connections ?

Dernière mise à jour : 14/06/2022

L'erreur « FATAL : remaining connection slots are reserved for non-replicate superuser connections » s'affiche lorsque je me connecte à mon Amazon Relational Database Service (Amazon RDS) for PostgreSQL alors que je n'ai pas atteint la limite max_connections.

Brève description

Dans Amazon RDS for PostgreSQL, le nombre maximum réel de connexions disponibles pour les utilisateurs standard est calculé comme suit :

max_connections - superuser_reserved_connections - rds.rds_superuser_reserved_connections.

La valeur par défaut de superuser_reserved_connections est 3, et la valeur par défaut pour rds.rds_superuser_reserved_connections est 2.

Par exemple, si vous définissez la valeur de max_connections sur 100, le nombre réel de connexions disponibles pour un utilisateur standard est calculé comme suit :

100 - 3 - 2 = 95.

La métrique DatabaseConnections d’Amazon CloudWatch indique le nombre de connexions réseau client à l'instance de base de données au niveau du système d'exploitation. Cette métrique est calculée en mesurant le nombre réel de connexions TCP vers l'instance sur le port 5432. Le nombre de sessions de base de données peut être supérieur à la valeur de cette métrique car cette dernière n'inclut pas les éléments suivants :

  • Les processus backend qui n'ont plus de connexion réseau mais qui ne sont pas nettoyés par la base de données (par exemple : la connexion est interrompue en raison de problèmes de réseau, mais la base de données n'en est informée que lorsqu'elle essaie de renvoyer la sortie au client)
  • Processus backend créés par les capacités d'exécution en parallèle du moteur de base de données
  • Processus backend créés par le planificateur de tâches du moteur de base de données (Par exemple : pg_cron)
  • Connexions Amazon RDS

Cette erreur peut se produire car l'application qui se connecte à l'instance RDS for PostgreSQL crée et supprime brusquement des connexions. Par conséquent, la connexion backend pourrait rester ouverte pendant un certain temps. Cette condition peut créer une divergence entre les valeurs de la vue pg_stat_activity et de la métrique DatabaseConnections de CloudWatch.

Résolution

Résoudre cette erreur

Pour résoudre cette erreur, effectuez les vérifications suivantes :

  • Passez en revue la métrique DatabaseConnections de CloudWatch.
  • Utilisez Performance Insights pour afficher la métrique de compteur numbackends. Cette valeur fournit des informations sur le nombre de connexions au moment où l'erreur s'est produite. Si vous n'avez pas activé Performance Insights, connectez-vous à votre instance en tant qu'utilisateur principal et affichez le nombre de backends en exécutant la requête suivante :
SELECT count(*) FROM pg_stat_activity;

Si vous trouvez des connexions inactives qui peuvent être interrompues, vous pouvez arrêter ces backends en utilisant la fonction pg_terminate_backend(). Vous pouvez afficher toutes les connexions inactives que vous souhaitez interrompre en exécutant la requête suivante. La requête suivante affiche des informations sur les processus backend présentant l'un des états suivants pendant plus de 15 minutes : « inactif », « inactif dans la transaction », « inactif dans la transaction (abandonné) » et « désactivé ».

SELECT * FROM pg_stat_activity
WHERE pid <> pg_backend_pid()
AND state in ('idle', 'idle in transaction', 'idle in transaction (aborted)', 'disabled')
AND state_change < current_timestamp - INTERVAL '15' MINUTE;

Remarque : veillez à mettre à jour la requête en fonction de votre cas d'utilisation.

Après avoir identifié tous les processus backend qui doivent être interrompus, interrompez-les en exécutant la requête suivante.

Remarque : cet exemple de requête interrompt tous les processus backend dans l'un des états mentionnés précédemment pendant plus de 15 minutes.

SELECT pg_terminate_backend(pid) FROM pg_stat_activity
WHERE pid <> pg_backend_pid()
AND state in ('idle', 'idle in transaction', 'idle in transaction (aborted)', 'disabled')
AND state_change < current_timestamp - INTERVAL '15' MINUTE
AND usename != 'rdsadmin';

Pour interrompre tous les processus backend inactifs, exécutez la requête suivante :

SELECT pg_terminate_backend(pid) FROM pg_stat_activity
WHERE pid <> pg_backend_pid()
AND state in ('idle', 'idle in transaction', 'idle in transaction (aborted)', 'disabled')
AND usename != 'rdsadmin';

Remarque : vous ne pouvez pas interrompre les processus backend créés avec rdsadmin. Par conséquent, vous devez les exclure de l’activité d’interruption.

Important : si vous ne parvenez pas à vous connecter à votre instance RDS for PostgreSQL avec les privilèges rds_superuser, pensez donc à fermer votre application correctement afin de libérer des connexions.

Gérer le nombre de connexions aux bases de données

Utiliser le regroupement de connexions

Dans la plupart des cas, vous pouvez utiliser un regroupement de connexions, tel qu'un Proxy RDS ou tout autre regroupement de connexions tiers, pour gérer le nombre de connexions ouvertes à un moment donné. Par exemple, si vous définissez la valeur max_connections de votre instance RDS for PostgreSQL sur 500, vous pouvez éviter les erreurs liées à max_connection en ayant un regroupement de connexions configuré pour un maximum de 400 connexions.

Augmenter la valeur max_connections

Vous pouvez envisager d'augmenter la valeur de max_connections en fonction de votre cas d'utilisation. Cependant, la définition d'une valeur très élevée pour max_connections peut entraîner des problèmes de mémoire en fonction de la charge de travail et de la classe d'instance de l'instance de base de données.

Remarque : si vous augmentez la valeur de max_connections, vous devez redémarrer l'instance pour que la modification soit prise en compte.

Interrompre les connexions inactives

Vous pouvez définir le paramètre idle_in_transaction_session_timeout sur une valeur adaptée à votre cas d'utilisation. Toute session inactive dans une transaction ouverte pendant une durée supérieure à celle spécifiée dans ce paramètre est interrompue. Par exemple, si vous définissez ce paramètre sur 10 minutes, toute requête inactive dans la transaction pendant plus de 10 minutes est interrompue. Ce paramètre permet de gérer les connexions se retrouvant bloquées dans cet état particulier.

Pour les versions 14 et ultérieures de PostgreSQL, vous pouvez utiliser le paramètre idle_session_timeout. Après avoir défini ce paramètre, toute session inactive pendant une durée supérieure à celle spécifiée, mais ne faisant pas partie d'une transaction ouverte, est interrompue.

Pour les versions 14 et ultérieures de PostgreSQL, vous pouvez utiliser le paramètre client_connection_check_interval. Ce paramètre vous permet de définir l'intervalle de temps entre les vérifications facultatives de la connexion client lors de l'exécution de requêtes. La vérification est effectuée en interrogeant le socket. Cette vérification permet de terminer plus tôt les requêtes de longue durée si le noyau signale que la connexion est fermée. Ce paramètre est utile dans les situations où PostgreSQL n'est pas au courant de la perte de connexion avec un processus backend.

Augmentez la valeur rds.rds_superuser_reserved_connections

Vous pouvez envisager d'augmenter la valeur du paramètre rds.rds_superuser_reserved_connections. La valeur par défaut de ce paramètre est 2. L'augmentation de la valeur de ce paramètre permet d'augmenter le nombre de connexions des utilisateurs ayant le rôle rds_superuser attaché. Avec ce rôle, les utilisateurs peuvent exécuter des tâches administratives, comme interrompre une connexion inactive à l'aide de la commande pg_terminate_backend().


Cet article vous a-t-il été utile ?


Avez-vous besoin d'aide pour une question technique ou de facturation ?