Wie kann ich herausfinden, was eine Abfrage auf einer DB-Instance blockiert, auf der Amazon-RDS-PostgreSQL oder Aurora-PostgreSQL ausgeführt wird?

Lesedauer: 4 Minute
0

Ich führe eine Abfrage auf einer DB-Instance aus, auf der Amazon Relational Database Service (Amazon RDS)-PostgreSQL oder Amazon-Aurora-PostgreSQL ausgeführt wird. Die Abfrage wird blockiert, obwohl keine anderen Abfragen gleichzeitig ausgeführt werden.

Lösung

Transaktionen, die nicht bestätigt wurden, können dazu führen, dass neue Abfragen blockiert werden, in den Ruhemodus versetzt werden und fehlschlagen, wenn sie das Wartezeitlimit für die Sperre oder das Zeitlimit für die Anweisung überschreiten. Um dieses Problem zu beheben, müssen Sie die Transaktion, die die Abfrage blockiert, identifizieren und beenden.

1.    Führen Sie die folgende Abfrage für die Ansicht pg_stat_activity aus, um den aktuellen Status der blockierten Transaktion zu ermitteln:

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

Hinweis: Ersetzen Sie TABLE NAME durch Ihren Tabellennamen oder Ihre Bedingung.

Wenn der Wert der Spalte wait_event_type Lock ist, wird die Abfrage durch andere Transaktionen oder Abfragen blockiert. Wenn die Spalte wait_event_type einen anderen Wert enthält, liegt ein Leistungsengpass bei Ressourcen wie CPU, Speicher oder Netzwerkkapazität vor. Um Leistungsengpässe zu beheben, optimieren Sie die Leistung Ihrer Datenbank. Sie können beispielsweise Indizes hinzufügen, Abfragen neu schreiben oder Vakuum- und Analysebefehle ausführen. Weitere Informationen finden Sie unter Bewährte Methoden für die Arbeit mit PostgreSQL.

Wenn Sie Performance Insights aktiviert haben, können Sie sich die Datenbanklast anzeigen lassen, die nach Warteereignissen, Hosts, SQL-Abfragen oder Benutzern gruppiert ist, um blockierte Transaktionen zu identifizieren. Weitere Informationen finden Sie unter Überwachen der DB-Auslastung mit Performance Insights auf Amazon RDS.

2.    Wenn der Wert der Spalte wait_event_type Lock lautet, führen Sie den folgenden Befehl 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;

3.    Überprüfen Sie die Spalten, die ein „Blockieren“-Präfix haben. In der folgenden Beispieltabelle können Sie sehen, dass die blockierte Transaktion auf dem Host 27.0.3.146 ausgeführt wird und psql verwendet. Verwenden Sie blocking_user, blocking_user_addr und blocking_client_port, um festzustellen, welche Sitzungen Transaktionen blockieren.

blocked_pid                           | 9069
blocked_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;

Wichtig: Bevor Sie Transaktionen beenden, sollten Sie die möglichen Auswirkungen der einzelnen Transaktionen auf den Status Ihrer Datenbank und Ihrer Anwendung abschätzen.

4.    Führen Sie die folgende Abfrage aus, um die Transaktionen zu stoppen:

SELECT pg_terminate_backend(PID);

Hinweis: Ersetzen Sie PID durch die blocking_pid des Prozesses, den Sie im vorherigen Schritt identifiziert haben.

Ähnliche Informationen

PostgreSQL-Dokumentation zum Anzeigen von Sperren

PostgreSQL-Dokumentation zu Server-Signalfunktionen

PostgreSQL-Dokumentation für wait_event description

PostgreSQL Wiki zur Sperrungsüberwachung

Amazon-Aurora-PostgreSQL-Warteereignisse