Direkt zum Inhalt

Wie behebe ich eine hohe CPU-Auslastung für Amazon RDS for PostgreSQL- oder Amazon Aurora PostgreSQL-kompatible Instances?

Lesedauer: 7 Minute
0

Ich möchte die hohe CPU-Auslastung in meiner Amazon Relational Database Service (Amazon RDS) for PostgreSQL- oder Amazon Aurora PostgreSQL-kompatiblen Edition-Instance beheben.

Lösung

Gehe wie folgt vor, um die Ursache für eine hohe CPU-Auslastung zu ermitteln. Reduziere dann die CPU-Auslastung deiner Datenbank-Instance (DB).

DB-Instance-Metriken überprüfen

Um zu ermitteln, wann deine Arbeitslast zu einer hohen CPU-Auslastung führt, verwende Amazon CloudWatch, um die Metriken WriteIOPs, ReadIOPs, ReadThroughput und WriteThroughput mit der Metrik CPUUtilization zu vergleichen. Für Aurora PostgreSQL-kompatibel kannst du auch die BufferCacheHitRatio-Metrik vergleichen. Wenn die Metrikwerte ähnlich hoch sind wie die CPUUtilization-Metrik, kann deine Arbeitslast die hohe CPU-Auslastung verursachen.

Enhanced Monitoring verwenden

Verwende Enhanced Monitoring, um das Betriebssystem (OS) für deine DB-Instance zu überprüfen. Um detaillierte Daten zu sammeln, lege die Granularity-Eigenschaft auf ein Intervall von 1, 5, 10, 15, 30 oder 60 Sekunden fest.

Um die Ursache der hohen CPU-Auslastung zu beheben, überprüfe die Betriebssystemmetrik LoadAverageMinute. Wenn der Lastdurchschnitt höher ist als die Anzahl der vCPUs, ist die Instance stark ausgelastet. Wenn der Lastdurchschnitt unter der Anzahl der vCPUs für die DB-Instance-Klasse liegt, wird die Anwendungslatenz wahrscheinlich nicht durch CPU-Drosselung verursacht.

Du kannst auch die Betriebssystemprozessliste für die DB-Instance überprüfen. Enhanced Monitoring kann maximal 100 Prozesse identifizieren, die sich auf die Leistung deiner Instance auswirken. Um die Ressourcenauslastung von Abfragen zu ermitteln, verwende die Enhanced Monitoring-Ergebnisse, um eine PostgreSQL-Abfrage vom Typ pg\ _stat\ _activity auszuführen.

CloudWatch Database Insights verwenden

Aktiviere Amazon CloudWatch Database Insights, um die Abfrage zu identifizieren, die für die DB-Auslastung verantwortlich ist. Überprüfe dann auf der Registerkarte Top SQL im DB-Lastdiagramm den spezifischen Zeitpunkt, zu dem die CPU-Auslastung zunimmt.

Native PostgreSQL-Ansichten und -Kataloge überprüfen

Bei Problemen in Echtzeit solltest du pg\ _stat\ _activity oder pg\ _stat\ _statements aktivieren, um Computer, Clients und IP-Adressen zu gruppieren, die den meisten Datenverkehr senden. Weitere Informationen findest du unter pg_stat_activity und pg_stat_statements auf der PostgreSQL-Website.

pg\ _stat\ _statements aktivieren

Führe die folgenden Schritte aus:

  1. Ändere die folgenden Werte deiner benutzerdefinierten DB-Parametergruppe:
    Füge pg_stat_statements zu shared_preload_libraries hinzu.
    Stelle track_activity_query_size auf 4096.
    Stelle pg_stat_statements.track auf „ALL“.
    Stelle pg_stat_statements.max auf 10000.
  2. Wähle Sofort anwenden und starte dann die DB-Instance neu.

Die zu überwachende Datenbank auswählen

Führe die folgende Abfrage aus:

select current_database();

Erweiterung in der aktuellen Datenbank installieren

Führe den folgenden Befehl aus:

CREATE EXTENSION IF NOT EXISTS pg_stat_statements;

Abfragen anzeigen, die in der Datenbank am meisten Zeit benötigen

Führe die folgende Abfrage für deine PostgreSQL-Version aus.

PostgreSQL Versionen 12 und früher:

SELECT total_time, query FROM pg_stat_statements ORDER BY total_time DESC LIMIT 10;

PostgreSQL Versionen 13 und höher:

SELECT total_plan_time+total_exec_time as total_time, query FROM pg_stat_statements ORDER BY 1 DESC LIMIT 10;

Abfragen mit einer niedrigeren Puffer-Cache-Trefferquote auflisten

Führe die folgende Abfrage für deine PostgreSQL-Version aus.

PostgreSQL Versionen 12 und früher:

SELECT query, calls, total_time, rows, 100.0 * shared_blks_hit / nullif(shared_blks_hit + shared_blks_read, 0) AS hit_percent FROM pg_stat_statements ORDER BY total_time DESC LIMIT 10;

PostgreSQL Versionen 13 und höher:

SELECT query, calls, total_plan_time+total_exec_time as total_time, rows, 100.0 * shared_blks_hit / nullif(shared_blks_hit +shared_blks_read, 0) AS hit_percent FROM pg_stat_statements ORDER BY 3 DESC LIMIT 10;

**Beispielabfragen im Zeitverlauf **

Führe die folgende Abfrage für deine PostgreSQL-Version aus.

PostgreSQL Versionen 12 und früher:

SELECT query, calls, total_time/calls as avg_time_ms, rows/calls as avg_rows,temp_blks_read/calls as avg_tmp_read, temp_blks_written/calls as avg_temp_written FROM pg_stat_statements WHERE calls != 0

ORDER BY total_time DESC LIMIT 10;

PostgreSQL Versionen 13 und höher:

SELECT query,calls,  (total_plan_time+total_exec_time as total_time)/calls as avg_time_ms,   
 rows/calls as avg_rows,  
temp_blks_read/calls as avg_tmp_read,  
 temp_blks_written/calls as avg_temp_written  
FROM pg_stat_statements  
WHERE calls != 0  
ORDER BY 3 DESC LIMIT 10;

Auf inaktive Verbindungen in der Datenbank überprüfen

Wenn du inaktive Verbindungen in der Datenbank hast, verbraucht die DB-Instance möglicherweise viel CPU. Um dieses Problem zu beheben, suche nach Verbindungen im Leerlauf und beende diese. Weitere Informationen findest du unter Performance impact of idle PostgreSQL connections (Auswirkungen von PostgreSQL-Verbindungen im Leerlauf auf die Leistung).

Führe die folgende Abfrage aus, um Sitzungen zu überprüfen, die länger als 10 Minuten inaktiv sind:

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

Führe die folgende Abfrage aus, um nur Sitzungen zu beenden, die sich länger als 10 Minuten im Ruhezustand befinden:

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 '10' MINUTE
AND usename != 'rdsadmin';

Führe eine der folgenden Abfragen aus, um alle inaktiven Verbindungen zu beenden:

SELECT pg_terminate_backend(pid)
FROM pg_stat_activity
WHERE usename = 'example-username'  
AND pid <> pg_backend_pid()  
AND state in ('idle');

**Hinweis:**Ersetze example-username durch deinen Benutzernamen.

-oder-

SELECT pg_terminate_backend (example-pid);

**Hinweis:**Ersetze example-pid durch deine Abfrage-PID.

Wenn deine Anwendung zu viele Datenbankverbindungen erstellt, reduziere die Anzahl der Verbindungen. Oder verwende einen Verbindungspooler wie PgBouncer. Weitere Informationen findest du unter PgBouncer auf der PgBouncer-Website. Du kannst Amazon-RDS-Proxy auch verwenden, um Verbindungspools einzurichten.

Nach Datenbanksperren suchen

Wenn deine Datenbanksperren dazu führen, dass sich Abfragen häufen und länger ausgeführt werden, kann sich die CPU-Auslastung deiner DB-Instance erhöhen. Um Probleme im Zusammenhang mit Sperren zu beheben, überprüfe Database Insights auf Warteereignisse wie Lock:Relation, Lock:tuple, Lock:transactionid oder andere Ereignisse im Zusammenhang mit Sperren.

Informationen darüber, was deine Abfrage blockiert hat, findest du unter Wie finde ich heraus, was eine Abfrage auf meiner Amazon RDS PostgreSQL- oder Aurora PostgreSQL-Datenbank-Instance blockiert hat?

Wenn Sperrsitzungen nicht ACTIVE sind, verwende Database Insights, um gesperrte Abfragen zu identifizieren. Um dieses Problem zu beheben, beende alle gesperrten Sitzungen.

Den Befehl ANALYZE ausführen

Wenn du ANALYZE nicht häufig für Tabellen in der Datenbank ausführst, verbrauchen die Abfragen aufgrund veralteter Statistiken im System möglicherweise mehr Rechenressourcen. Weitere Informationen findest du unter ANALYZE auf der PostgreSQL-Website.

Autovacuum entfernt ungenutzten Speicherplatz aus Tabellen und gibt Speicherplatz in deiner Datenbank zurück. Der Autovacuum-Daemon führt auch den Befehl ANALYZE aus, um die Tabellenstatistiken regelmäßig zu aktualisieren, wenn du den Schwellenwert früherer Versionen erreichst, die du konfiguriert hast.

Um zu erfahren, wann Autovacuum und Autoanalyze zuletzt für die Tabellen ausgeführt wurden, führe die folgende Abfrage aus:

SELECT relname, last_autovacuum, last_autoanalyze FROM pg_stat_user_tables;

Um Leistungsprobleme nach einer Aktualisierung der Hauptversion der Engine zu vermeiden, führe den Befehl ANALYZE aus, um die Tabelle pg_statistic für jede Datenbank in deiner DB-Instance zu aktualisieren.

Um Leistungsprobleme aufgrund einer höheren Ressourcenauslastung zu vermeiden, führe den folgenden Befehl ohne Parameter aus, um alle Statistiken neu zu generieren:

ANALYZE VERBOSE;

PostgreSQL-Fehlerprotokolle überprüfen

Aktiviere die Abfrageprotokollierung in Amazon RDS for PostgreSQL. Überprüfe anschließend die PostgreSQL-Fehlerprotokolle, um sicherzustellen, dass du die Parameter log_min_duration_statement und log_statement eingestellt hast. Weitere Informationen findest du unter Error reporting and logging (Fehlerberichterstattung und Protokollierung) auf der PostgreSQL-Website.

CPU-Auslastung reduzieren

Gehe wie folgt vor, um die CPU-Auslastung zu reduzieren:

  • Verwende EXPLAIN und EXPLAIN ANALYZE, um Möglichkeiten zur Optimierung von Abfrageplänen zu identifizieren. Weitere Informationen findest du unter Using EXPLAIN (Verwendung von EXPLAIN) auf der PostgreSQL-Website.
  • Wenn du Sperrsitzungen identifizierst, die nicht erforderlich sind, verwende die PID der Sperrsitzung, um die Sitzungen zu beenden.
  • Wenn du eine Abfrage wiederholt ausführst, verwende vorbereitete Anweisungen, um die CPU-Auslastung zu senken. Weitere Informationen findest du unter PREPARE auf der PostgreSQL-Website.

Weitere Informationen

Bewährte Methoden für die Arbeit mit PostgreSQL

Betriebssystem-Überwachung

Grundlegendes zum Autovacuum in Amazon RDS für PostgreSQL-Umgebungen

Eine Fallstudie zur Optimierung des Autovacuum in Amazon RDS für PostgreSQL

AWS OFFICIALAktualisiert vor 4 Monaten