Wie kann ich Sperren in Amazon Redshift erkennen und freigeben?

Lesedauer: 4 Minute
0

Es gibt Tabellensperren, die meine Abfragen in Amazon Redshift blockieren. Wie kann ich sie finden und das Problem lösen?

Kurzbeschreibung

Das Sperren ist ein Schutzmechanismus, der steuert, wie viele Sitzungen gleichzeitig auf eine Tabelle zugreifen können. Das Sperren bestimmt auch, welche Transaktionen in diesen Sitzungen ausgeführt werden können. Die meisten relationalen Datenbanken verwenden Sperren auf Zeilenebene. Amazon Redshift verwendet jedoch Sperren auf Tabellenebene. Es kann zu Sperrkonflikten kommen, wenn Sie häufig DDL-Anweisungen für Benutzertabellen oder DML-Abfragen ausführen.

Amazon Redshift verfügt über drei Sperrmodi:

  • AccessExclusiveLock: Wird hauptsächlich während DDL-Operationen wie TABELLE ÄNDERN; FALLENLASSEN oder KÜRZEN erworben. AccessExclusiveLock blockiert alle anderen Sperrversuche.
  • **AccessShareLock:**Erworben bei AUSLADEN-, AUSWÄHLEN-, AKTUALISIEREN- oder LÖSCHEN-Operationen. AccessShareLock blockiert nur AccessExclusiveLock-Versuche. AccessShareLock blockiert keine anderen Sitzungen, die versuchen, die Tabelle zu lesen oder darin zu schreiben.
  • ShareRowExclusiveLock: Erworben bei KOPIEREN-, EINFÜGEN-, AKTUALISIEREN- oder LÖSCHEN-Operationen. ShareRowExclusiveLock blockiert AccessExclusiveLock und andere ShareRowExclusiveLock-Versuche, blockiert jedoch keine AccessShareLock-Versuche.

Wenn eine Abfrage oder Transaktion eine Sperre für eine Tabelle erwirbt, bleibt die Sperre für die Dauer der Abfrage oder Transaktion bestehen. Andere Abfragen oder Transaktionen, die darauf warten, dieselbe Sperre zu erhalten, werden mit Ausnahme von AccessShareLock blockiert. Weitere Informationen darüber, warum eine Abfrage hängen bleiben kann, finden Sie unter Anfrage hängt.

Um ein Sperrproblem zu lösen, identifizieren Sie die Sitzung (PID), die die Sperre hält, und beenden Sie dann die Sitzung. Wenn die Sitzung nicht beendet wird, starten Sie Ihren Cluster neu.

Behebung

Führen Sie eine Abfrage aus, um gesperrte Sitzungen zu identifizieren:

select a.txn_owner, a.txn_db, a.xid, a.pid, a.txn_start, a.lock_mode, a.relation as table_id,nvl(trim(c."name"),d.relname) as tablename, a.granted,b.pid as blocking_pid ,datediff(s,a.txn_start,getdate())/86400||' days '||datediff(s,a.txn_start,getdate())%86400/3600||' hrs '||datediff(s,a.txn_start,getdate())%3600/60||' mins '||datediff(s,a.txn_start,getdate())%60||' secs' as txn_duration
from svv_transactions a
left join (select pid,relation,granted from pg_locks group by 1,2,3) b
on a.relation=b.relation and a.granted='f' and b.granted='t'
left join (select * from stv_tbl_perm where slice=0) c
on a.relation=c.id
left join pg_class d on a.relation=d.oid
where  a.relation is not null;

Die Ausgabe sieht etwa so aus:

txn_owner | txn_db |   xid   |  pid  |         txn_start          |      lock_mode      | table_id | tablename | granted | blocking_pid |        txn_duration         |
----------+--------+---------+-------+----------------------------+---------------------+----------+-----------+---------+--------------+-----------------------------+
 usr1     | db1    | 5559898 | 19813 | 2018-06-30 10:51:57.485722 | AccessExclusiveLock |   351959 | lineorder | t       |              | 0 days 0 hrs 0 mins 52 secs |
 usr1     | db1    | 5559927 | 20450 | 2018-06-30 10:52:19.761199 | AccessShareLock     |   351959 | lineorder | f       |        19813 | 0 days 0 hrs 0 mins 30 secs |
 usr1     | db1    | 5559898 | 19813 | 2018-06-30 10:51:57.485722 | AccessShareLock     |   351959 | lineorder | t       |              | 0 days 0 hrs 0 mins 52 secs |

Wenn das Ergebnis in der Spalte gewährt f (falsch) ist, ist die Sperre für eine Transaktion in einer anderen Sitzung reserviert. In der Spalte blocking\ _pid wird die Prozess-ID der Sitzung angezeigt, für die die Sperre gilt. In diesem Beispiel ist die Sperre für PID 19813 reserviert.

Um eine Sperre aufzuheben, warten Sie, bis die Transaktion, für die die Sperre gilt, abgeschlossen ist. Sie können die Sitzung auch manuell beenden, indem Sie den folgenden Befehl ausführen:

select pg_terminate_backend(PID);

Durch das Beenden einer PID werden alle laufenden Transaktionen rückgängig gemacht und alle Sperren in der Sitzung aufgehoben. Die Sperren werden dann von den anderen Transaktionen in Anspruch genommen, die darauf warten, die Sperre zu erhalten.

Hinweis: Der von PG\ _TERMINATE\ _BACKEND (PID) zurückgegebene Wert „1“ weist in der Regel auf eine erfolgreiche Beendigungsanfrage an die PID hin. Dies garantiert jedoch nicht, dass die PID tatsächlich beendet wurde. In einigen Fällen kann die PID je nach internem Status nicht bestimmt werden. Daher empfiehlt es sich, auch STV\ _SESSIONS (und andere relevante Systemtabellen) zu überprüfen, um zu bestätigen, dass die PID tatsächlich beendet wurde.

Wenn PG\ _TERMINATE\ _BACKEND (PID) die Sitzung nicht erfolgreich beendet, starten Sie den Cluster neu, um den Prozess zu beenden. Der Neustart kann durch einen Cluster-Neustart über die Amazon Redshift-Konsole oder durch einen Datenbank-Neustart mit REBOOT_CLUSTER. durchgeführt werden.


Verwandte Informationen

SPERREN (Amazon Redshift)

Mögliche Deadlock-Situation für gleichzeitige Schreibtransaktionen

AWS OFFICIAL
AWS OFFICIALAktualisiert vor 2 Jahren