Direkt zum Inhalt

Wie finde ich heraus, was eine Abfrage auf meiner DB-Instance von Amazon RDS für PostgreSQL oder Aurora PostgreSQL-Compatible blockiert hat?

Lesedauer: 3 Minute
0

Ich möchte eine blockierte Abfrage auf meiner Datenbank (DB)-Instance von Amazon Relational Database Service (Amazon RDS) für PostgreSQL oder von Amazon Aurora PostgreSQL-Compatible Edition beheben.

Lösung

Nicht festgeschriebene Transaktionen können neue Abfragen blockieren, sie in den Ruhezustand versetzen oder dazu führen, dass sie fehlschlagen, wenn sie das Timeout beim Warten auf die Sperre oder das Timeout für die Anweisung überschreiten. Um dieses Problem zu lösen, identifiziere und stoppe die nicht bestätigten Transaktionen.

Blockierte Transaktionen identifizieren

Um blockierte Transaktionen zu identifizieren, aktiviere Performance Insights und verwende Database Insights. Verwende das Datenbanklastdiagramm, um die Dimensionen der Datenbanklast für Wartezeiten, Host, SQL oder Benutzer:in anzuzeigen. Weitere Informationen findest du unter Überwachen der DB-Last mit Performance Insights auf Amazon RDS.

Führe die folgende Anweisung aus, um den aktuellen Status der blockierten Transaktion zu ermitteln:

SELECT * FROM pg_stat_activity WHERE query iLIKE '%TABLE NAME%' ORDER BY state;

Hinweis: Ersetze TABLE NAME durch deinen Tabellennamen oder deine Bedingung.

Wenn der Wert in der Spalte wait_event_type nicht Lock (Sperren) lautet, liegt ein Leistungsengpass bei Ressourcen wie CPU, Speicher oder Netzwerkkapazität vor. Um Leistungsengpässe zu beheben, optimiere die Leistung deiner Datenbank. Du kannst beispielsweise Indizes hinzufügen, Abfragen neu schreiben oder Bereinigungs- und Analysebefehle ausführen. Weitere Informationen findest du unter Bewährte Methoden für die Arbeit mit PostgreSQL.

Wenn der Wert der Spalte wait_event_type Lock (Sperren) ist, blockieren andere Transaktionen oder Abfragen die Abfrage. Führe die folgende Anweisung aus, um die Ursache der blockierten Transaktion zu ermitteln:

SELECT blocked_locks.pid     AS blocked_pid,       blocked_activity.usename  AS blocked_user,  
       blocked_activity.client_addr as blocked_client_addr,  
       blocked_activity.client_hostname as blocked_client_hostname,  
       blocked_activity.client_port as blocked_client_port,  
       blocked_activity.application_name as blocked_application_name,  
       blocked_activity.wait_event_type as blocked_wait_event_type,  
       blocked_activity.wait_event as blocked_wait_event,  
       blocked_activity.query    AS blocked_statement,  
       blocking_locks.pid     AS blocking_pid,  
       blocking_activity.usename AS blocking_user,  
       blocking_activity.client_addr as blocking_user_addr,  
       blocking_activity.client_hostname as blocking_client_hostname,  
       blocking_activity.client_port as blocking_client_port,  
       blocking_activity.application_name as blocking_application_name,  
       blocking_activity.wait_event_type as blocking_wait_event_type,  
       blocking_activity.wait_event as blocking_wait_event,  
       blocking_activity.query   AS current_statement_in_blocking_process  
 FROM  pg_catalog.pg_locks         blocked_locks  
    JOIN pg_catalog.pg_stat_activity blocked_activity ON blocked_activity.pid = blocked_locks.pid  
    JOIN pg_catalog.pg_locks         blocking_locks   
        ON blocking_locks.locktype = blocked_locks.locktype  
        AND blocking_locks.DATABASE IS NOT DISTINCT FROM blocked_locks.DATABASE  
        AND blocking_locks.relation IS NOT DISTINCT FROM blocked_locks.relation  
        AND blocking_locks.page IS NOT DISTINCT FROM blocked_locks.page  
        AND blocking_locks.tuple IS NOT DISTINCT FROM blocked_locks.tuple  
        AND blocking_locks.virtualxid IS NOT DISTINCT FROM blocked_locks.virtualxid  
        AND blocking_locks.transactionid IS NOT DISTINCT FROM blocked_locks.transactionid  
        AND blocking_locks.classid IS NOT DISTINCT FROM blocked_locks.classid  
        AND blocking_locks.objid IS NOT DISTINCT FROM blocked_locks.objid  
        AND blocking_locks.objsubid IS NOT DISTINCT FROM blocked_locks.objsubid  
        AND blocking_locks.pid != blocked_locks.pid  
    JOIN pg_catalog.pg_stat_activity blocking_activity ON blocking_activity.pid = blocking_locks.pid  
   WHERE NOT blocked_locks.granted ORDER BY blocked_activity.pid;

Um festzustellen, welche Sitzungen Transaktionen blockieren, überprüfe die Werte blocking_user, blocking_user_addr und blocking_client_port. In der folgenden Beispielausgabe verwendet der/die Master-Benutzer:in psql, um die Transaktion zu blockieren, die auf dem 27.0.3.146-Host ausgeführt wird. Die blocking_pid ist 8740.

blocked_pid                           | 9069blocked_user                          | master  
blocked_client_addr                   | 27.0.3.146  
blocked_client_hostname               |  
blocked_client_port                   | 50035  
blocked_application_name              | psql  
blocked_wait_event_type               | Lock  
blocked_wait_event                    | transactionid  
blocked_statement                     | UPDATE test_tbl SET name = 'Jane Doe' WHERE id = 1;  
blocking_pid                          | 8740  
blocking_user                         | master  
blocking_user_addr                    | 27.0.3.146  
blocking_client_hostname              |  
blocking_client_port                  | 26259  
blocking_application_name             | psql  
blocking_wait_event_type              | Client  
blocking_wait_event                   | ClientRead  
current_statement_in_blocking_process | UPDATE tset_tbl SET name = 'John Doe' WHERE id = 1;

Transaktionen stoppen

Bevor du Transaktionen beendest, solltest du die möglichen Auswirkungen der einzelnen Transaktionen auf den Status deiner Datenbank und deiner Anwendung abschätzen.

Führe die folgende Anweisung aus, um die Transaktionen zu stoppen:

SELECT pg_terminate_backend(PID);

Hinweis: Ersetze PID durch die blocking_pid der Transaktion.

Ähnliche Informationen

Amazon-Aurora-PostgreSQL-Warteereignisse

AWS OFFICIALAktualisiert vor 10 Monaten