Warum erhalte ich den Fehler „FATAL: Verbleibende Verbindungssteckplätze sind für nicht replizierte Superuser-Verbindungen reserviert“, wenn ich mich mit meinem Amazon RDS für PostgreSQL verbinde, obwohl ich das max_connections-Limit nicht erreicht habe?

Lesedauer: 5 Minute
0

Ich erhalte den Fehler „FATAL: Verbleibende Verbindungssteckplätze sind für nicht replizierte Superuser-Verbindungen reserviert“, wenn ich eine Verbindung zu meinem Amazon Relational Database Service (Amazon RDS) für PostgreSQL herstelle, obwohl ich das max_connections-Limit nicht erreicht habe.

Kurzbeschreibung

In Amazon RDS für PostgreSQL wird die tatsächliche maximale Anzahl verfügbarer Verbindungen zu Nicht-Superusern wie folgt berechnet:

max_connections - superuser_reserved_connections - rds.rds_superuser_reserved_connections.

Der Standardwert für superuser_reserved_connections ist 3, und der Standardwert für rds.rds_superuser_reserved_connections ist 2.

Wenn Sie beispielsweise den Wert von max_connections auf 100 festlegen, wird die tatsächliche Anzahl der verfügbaren Verbindungen für einen Nicht-Superuser wie folgt berechnet:

100 - 3 - 2 = 95.

Die Amazon-CloudWatch-Metrik DatabaseConnections gibt die Anzahl der Client-Netzwerkverbindungen zur Datenbank-Instance auf Betriebssystemebene an. Diese Metrik wird berechnet, indem die tatsächliche Anzahl von TCP-Verbindungen zur Instance auf Port 5432 gemessen wird. Die Anzahl der Datenbanksitzungen kann höher als dieser Metrikwert sein, da der Metrikwert Folgendes nicht enthält:

  • Backend-Prozesse, die keine Netzwerkverbindung mehr haben, aber nicht von der Datenbank bereinigt werden. (Beispiel: Die Verbindung wird aufgrund von Netzwerkproblemen beendet, aber die Datenbank erkennt dies erst, wenn sie versucht, die Ausgabe an den Client zurückzugeben.)
  • Backend-Prozesse, die vom Job-Scheduler der Datenbank-Engine erstellt wurden. (Zum Beispiel: pg_cron)
  • Amazon-RDS-Verbindungen.

Dieser Fehler kann auftreten, weil die Anwendung, die eine Verbindung zur RDS-für-PostgreSQL-Instance herstellt, abrupt Verbindungen erstellt und löscht. Dies kann dazu führen, dass die Backend-Verbindung noch einige Zeit geöffnet ist. Diese Bedingung kann zu einer Diskrepanz zwischen den Werten der Ansicht pg_stat_activity und der CloudWatch-Metrik DatabaseConnections führen.

Auflösung

Fehlerbehebung

Führen Sie die folgenden Checks durch, um diesen Fehler zu beheben:

  • Überprüfen Sie die CloudWatch-Metrik „DatabaseConnections“.
  • Verwenden Sie Performance Insights, um die Zählermetrik numbackends anzuzeigen. Dieser Wert gibt Auskunft über die Anzahl der Verbindungen zum Zeitpunkt des Auftretens des Fehlers. Wenn Sie Performance Insights nicht aktiviert haben, melden Sie sich als primärer Benutzer bei Ihrer Instance an. Zeigen Sie dann die Anzahl der Backends an, indem Sie die folgende Abfrage ausführen:
SELECT count(*) FROM pg_stat_activity;

Wenn Sie einige Verbindungen im Leerlauf finden, die beendet werden können, können Sie diese Backends mit der Funktion pg_terminate_backend() beenden. Sie können alle Verbindungen im Leerlauf anzeigen, die Sie beenden möchten, indem Sie die folgende Abfrage ausführen. Diese Abfrage zeigt Informationen zu Backend-Prozessen mit einem der folgenden Status für mehr als 15 Minuten an: „inaktiv“, „inaktiv in Transaktion“, „inaktiv in Transaktion (abgebrochen)“ und „deaktiviert“.

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;

Hinweis: Achten Sie darauf, die Abfrage entsprechend Ihrem Anwendungsfall zu aktualisieren.

Nachdem Sie alle Backend-Prozesse identifiziert haben, die beendet werden müssen, beenden Sie diese Prozesse, indem Sie die folgende Abfrage ausführen.

Hinweis: Diese Beispielabfrage beendet alle Backend-Prozesse in einem der zuvor genannten Zustände für mehr als 15 Minuten.

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

Führen Sie die folgende Abfrage aus, um alle Backend-Prozesse im Leerlauf zu beenden:

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

Hinweis: Sie können Backend-Prozesse, die mit rdsadmin erstellt wurden, nicht beenden. Daher müssen Sie sie von dem Beenden ausschließen.

Wichtig: Wenn Sie mit der Berechtigung rds_superuser keine Verbindung zu Ihrer RDS-für-PostgreSQL-Instance herstellen können, sollten Sie erwägen, Ihre Anwendung ordnungsgemäß zu schließen, um einige Verbindungen freizugeben.

Anzahl der Datenbankverbindungen verwalten

Verbindungs-Pooling

In den meisten Fällen können Sie einen Verbindungspool verwenden, z. B. einen RDS-Proxy oder einen Verbindungspool eines Drittanbieters, um die Anzahl der Verbindungen zu verwalten, die zu einem bestimmten Zeitpunkt geöffnet sind. Wenn Sie beispielsweise den Wert „max_connections“ Ihrer RDS-für-PostgreSQL-Instance auf 500 festlegen, können Sie Fehler im Zusammenhang mit „max_connection“ verhindern, indem Sie einen Connection Pooler haben, der für maximal 400 Verbindungen konfiguriert ist.

Wert von „max_connections“ erhöhen

Sie könnten erwägen, den Wert von „max_connections“ abhängig von Ihrem Anwendungsfall zu erhöhen. Das Festlegen eines sehr hohen Werts für „max_connections“ kann jedoch zu Speicherproblemen führen, abhängig von der Workload- und Instance-Klasse der Datenbank-Instance.

Hinweis: Wenn Sie den Wert von „max_connections“ erhöhen, müssen Sie die Instance neu starten, damit die Änderung wirksam wird.

Verbindungen im Leerlauf beenden

Sie können den Parameter idle_in_transaction_session_timeout auf einen Wert setzen, der für Ihren Anwendungsfall geeignet ist. Jede Sitzung, die sich in einer offenen Transaktion länger als die in diesem Parameter angegebene Zeit im Leerlauf befindet, wird beendet. Wenn Sie diesen Parameter beispielsweise auf 10 Minuten festlegen, wird jede Abfrage beendet, die länger als 10 Minuten in der Transaktion inaktiv ist. Dieser Parameter hilft bei der Verwaltung von Verbindungen, die in diesem bestimmten Zustand stecken bleiben.

Für PostgreSQL-Versionen 14 und höher können Sie den Parameter idle_session_timeout verwenden. Nachdem Sie diesen Parameter festgelegt haben, wird jede Sitzung beendet, die sich länger als die angegebene Zeit im Leerlauf befindet, jedoch nicht innerhalb einer offenen Transaktion.

Für PostgreSQL-Versionen 14 und höher können Sie den Parameter client_connection_check_interval verwenden. Mit diesem Parameter können Sie das Zeitintervall zwischen optionalen Checks für die Clientverbindung beim Ausführen von Abfragen festlegen. Der Check erfolgt durch Abfragen des Sockets. Durch diesen Check können Abfragen mit langer Ausführungsdauer früher beendet werden, wenn der Kernel meldet, dass die Verbindung geschlossen ist. Dieser Parameter hilft in Situationen, in denen PostgreSQL nichts über die abgebrochene Verbindung mit einem Backend-Prozess weiß.

Wert „rds.rds_superuser_reserved_connections“ erhöhen

Sie könnten erwägen, den Wert des Parameters rds.rds_superuser_reserved_connections zu erhöhen. Der Standardwert für diesen Parameter ist auf 2 festgelegt. Das Erhöhen des Werts dieses Parameters ermöglicht mehr Verbindungen von Benutzern mit der angehängten rds_superuser-Rolle. Mit dieser Rolle können die Benutzer administrative Aufgaben ausführen, z. B. das Beenden einer Verbindung im Leerlauf mithilfe des Befehls pg_terminate_backend().


AWS OFFICIAL
AWS OFFICIALAktualisiert vor 2 Jahren