Perché ricevo l'errore "FATAL: gli slot di connessione rimanenti sono riservati per connessioni superuser non replicate" quando mi connetto all'istanza Amazon RDS per PostgreSQL anche se non ho raggiunto il limite max_connections?

Ultimo aggiornamento: 12 ottobre 2022

Ricevo l'errore "FATAL: gli slot di connessione rimanenti sono riservati per connessioni superuser non replicate" quando mi connetto all’Amazon Relational Database Service (Amazon RDS) per PostgreSQL anche se non ho raggiunto il limite max_connections.

Breve descrizione

In Amazon RDS per PostgreSQL, il numero massimo effettivo di connessioni disponibili per utenti non superuser viene calcolato come segue:

max_connections - superuser_reserved_connections - rds.rds_superuser_reserved_connections.

Il valore predefinito per superuser_reserved_connections è 3 e il valore predefinito per rds.rds_superuser_reserved_connections è 2.

Ad esempio, se si imposta il valore di max_connections su 100, il numero effettivo di connessioni disponibili per un utente non superuser viene calcolato come segue:

100 - 3 - 2 = 95.

La metrica DatabaseConnections di Amazon CloudWatch indica il numero di connessioni di rete client all'istanza del database a livello di sistema operativo. Questa metrica viene calcolata misurando il numero effettivo di connessioni TCP all'istanza sulla porta 5432. Il numero di sessioni del database potrebbe essere superiore a questo valore della metrica perché quest'ultimo non include quanto segue:

  • Processi di backend che non dispongono più di una connessione di rete ma non vengono ripuliti dal database. (Ad esempio: la connessione viene interrotta a causa di problemi di rete, ma il database non ne è a conoscenza finché non tenta di restituire l'output al client.)
  • Processi di backend creati dall'utilità di pianificazione dei processi del motore di database. (Ad esempio: pg_cron)
  • Connessioni Amazon RDS.

Potresti ricevere questo errore perché l'applicazione che si connette all'istanza RDS per PostgreSQL crea e interrompe improvvisamente le connessioni. Ciò potrebbe far sì che la connessione di backend rimanga aperta per qualche tempo. Questa condizione potrebbe creare una discrepanza tra i valori della visualizzazione pg_stat_activity e la metrica DatabaseConnections di CloudWatch.

Risoluzione

Risolvi l'errore

Per risolvere questo errore, esegui le seguenti verifiche:

  • Verifica la metrica DatabaseConnections di CloudWatch.
  • Usa Performance Insights per visualizzare la metrica del contatore numbackends. Questo valore fornisce informazioni sul numero di connessioni nel momento in cui si è verificato l'errore. Se non hai attivato Performance Insights, accedi alla tua istanza come utente principale. Quindi, visualizza il numero di backend eseguendo la seguente query:
SELECT count(*) FROM pg_stat_activity;

Se trovi alcune connessioni inattive che possono essere terminate, puoi terminare questi back-end usando la funzione pg_terminate_backend(). È possibile visualizzare tutte le connessioni inattive che si desidera terminare eseguendo la query seguente. La seguente query visualizza le informazioni sui processi di back-end con uno dei seguenti stati per più di 15 minuti: "idle", "idle in transaction", "idle in transaction (aborted)" e "disabled".

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;

Nota: assicurati di aggiornare la query in base al tuo caso d'uso.

Dopo aver identificato tutti i processi di backend che devono essere terminati, terminali eseguendo la query seguente.

Nota: questa query di esempio termina tutti i processi di back-end che si trovano in uno degli stati menzionati in precedenza per più di 15 minuti.

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

Per terminare tutti i processi di back-end inattivi, esegui la query seguente:

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

Nota: non è possibile terminare i processi di backend creati con rdsadmin. Pertanto, è necessario escluderli dalla risoluzione.

Importante: se non riesci a connetterti all'istanza RDS per PostgreSQL con i privilegi rds_superuser, considera la possibilità di chiudere l'applicazione correttamente per liberare alcune connessioni.

Gestisci il numero di connessioni al database

Usa il pool di connessioni

Nella maggior parte dei casi, è possibile utilizzare un pool di connessioni, ad esempio un proxy RDS o qualsiasi pool di connessioni di terze parti, per gestire il numero di connessioni aperte in un dato momento. Ad esempio, se si imposta il valore max_connections dell'istanza RDS per PostgreSQL su 500, è possibile evitare errori relativi a max_connection disponendo di un pool di connessioni configurato per un massimo di 400 connessioni.

Aumenta il valore max_connections

Potresti considerare di aumentare il valore di max_connections a seconda del tuo caso d'uso. Tuttavia, l'impostazione di un valore molto alto per max_connections potrebbe causare problemi di memoria in base al carico di lavoro e alla classe di istanza dell'istanza del database.

Nota: se si aumenta il valore di max_connections, è necessario riavviare l'istanza affinché la modifica abbia effetto.

Termina le connessioni inattive

È possibile impostare il parametro idle_in_transaction_session_timeout su un valore appropriato per il proprio caso d'uso. Qualsiasi sessione inattiva all'interno di una transazione aperta per un periodo superiore al tempo specificato in questo parametro viene terminata. Ad esempio, se si imposta questo parametro su 10 minuti, qualsiasi query inattiva nella transazione per più di 10 minuti viene terminata. Tale parametro aiuta a gestire le connessioni bloccate in questo stato specifico.

Per PostgreSQL versione 14 e successive, è possibile utilizzare il parametro idle_session_timeout. Dopo aver impostato questo parametro, qualsiasi sessione inattiva per più del tempo specificato, ma non all'interno di una transazione aperta, viene terminata.

Per PostgreSQL versione 14 e successive, è possibile utilizzare il parametro client_connection_check_interval. Con questo parametro è possibile impostare l'intervallo di tempo tra i controlli facoltativi per la connessione client durante l'esecuzione di query. Il controllo viene eseguito tramite il polling del socket. Questo controllo consente di terminare prima le query di lunga durata se il kernel segnala che la connessione è chiusa. Questo parametro aiuta in situazioni in cui PostgreSQL non è a conoscenza della connessione persa con un processo di backend.

Aumenta il valore di rds.rds_superuser_reserved_connections

È possibile aumentare il valore del parametro rds.rds_superuser_reserved_connections. Il valore predefinito per questo parametro è impostato su 2. L'aumento del valore di questo parametro consente più connessioni da parte di utenti con il ruolo rds_superuser associato. Con questo ruolo, gli utenti possono eseguire attività amministrative, ad esempio terminare una connessione inattiva utilizzando il comando pg_terminate_backend().


Questo articolo è stato utile?


Benötigen Sie Hilfe zur Fakturierung oder technischen Support?