Serialisierbare Isolierung - Amazon Redshift

Die vorliegende Übersetzung wurde maschinell erstellt. Im Falle eines Konflikts oder eines Widerspruchs zwischen dieser übersetzten Fassung und der englischen Fassung (einschließlich infolge von Verzögerungen bei der Übersetzung) ist die englische Fassung maßgeblich.

Serialisierbare Isolierung

Einige Anwendungen erfordern nicht nur gleichzeitiges Abfragen und Laden, sondern auch die Fähigkeit, gleichzeitig zu mehreren Tabellen oder zur selben Tabelle zu schreiben. In diesem Zusammenhang bedeutet gleichzeitig überlappend, nicht die Ausführung zu exakt demselben Zeitpunkt. Zwei Transaktionen werden als gleichzeitig betrachtet, wenn die zweite Transaktion gestartet wird, bevor für die erste Transaktion ein Commit ausgeführt wird. Gleichzeitige Operationen können ihren Ursprung in verschiedenen Sitzungen haben, die vom selben Benutzer oder von verschiedenen Benutzern kontrolliert werden.

Anmerkung

Amazon Redshift unterstützt ein standardmäßiges automatisches Commit-Verhalten, bei dem jeder separat ausgeführte SQL Befehl einzeln festgeschrieben wird. Wenn Sie in einem Transaktionsblock einen Satz von Befehlen einschließen (definiert durch die Anweisungen BEGIN und END), wird der Block als eine einzige Transaktion übergeben, sodass Sie ein Rollback für ihn ausführen können, wenn notwendig. Ausnahmen von diesem Verhalten sind die VACUUM Befehle TRUNCATE und, mit denen alle ausstehenden Änderungen, die in der aktuellen Transaktion vorgenommen wurden, automatisch übernommen werden.

Manche SQL Clients geben BEGIN COMMIT Befehle automatisch aus, sodass der Client kontrolliert, ob eine Gruppe von Anweisungen als Transaktion oder jede einzelne Anweisung als eigene Transaktion ausgeführt wird. Konsultieren Sie die Dokumentation zu der von Ihnen verwendeten Schnittstelle. Wenn Sie beispielsweise den Amazon Redshift JDBC Redshift-Treiber verwenden, führt ein Befehl JDBC PreparedStatement mit einer Abfragezeichenfolge, die mehrere (durch Semikolons getrennte) SQL Befehle enthält, alle Anweisungen als eine einzige Transaktion aus. Wenn Sie dagegen SQL Workbench/J verwenden und AUTO COMMIT ON setzen, wird bei der Ausführung mehrerer Anweisungen jede Anweisung als eigene Transaktion ausgeführt.

Gleichzeitige Schreiboperationen werden in Amazon Redshift auf geschützte Art unterstützt, indem Schreibsperren für Tabellen und der Grundsatz der serialisierbaren Isolierung angewendet werden. Die serialisierbare Isolierung bewahrt die Illusion, dass eine Transaktion, die für eine Tabelle ausgeführt wird, die einzige Transaktion ist, die für diese Tabelle ausgeführt wird. Beispielsweise müssen zwei gleichzeitig ausgeführte Transaktionen T1 und T2 in mindestens einer der folgenden Varianten dieselben Ergebnisse produzieren:

  • T1 und T2 werden seriell in dieser Reihenfolge ausgeführt.

  • T2 und T1 werden seriell in dieser Reihenfolge ausgeführt.

Gleichzeitige Transaktionen können sich gegenseitig nicht sehen, d. h., sie können die Änderungen der jeweils anderen Transaktionen nicht erkennen. Jede gleichzeitige Transaktion erstellt zu Beginn der Transaktion einen Snapshot der Datenbank. Ein Datenbanksnapshot wird innerhalb einer Transaktion beim ersten Auftreten der meisten SELECT Anweisungen, DML Befehle wieCOPY, DELETE INSERT UPDATETRUNCATE, und und der folgenden Befehle erstellt: DDL

  • ALTERTABLE(um Spalten hinzuzufügen oder zu löschen)

  • CREATE TABLE

  • DROP TABLE

  • TRUNCATE TABLE

Wenn eine beliebige serielle Ausführung der gleichzeitigen Transaktionen dieselben Ergebnisse wie ihre gleichzeitige Ausführung produzieren würde, gelten diese Transaktionen als „serialisierbar“ und können sicher ausgeführt werden. Wenn keine serielle Ausführung dieser Transaktionen dieselben Ergebnisse produziert, wird die Transaktion abgebrochen, die eine Anweisung ausführt, die die Serialisierbarkeit verhindern würde. Für diese Transaktion wird ein Rollback ausgeführt.

Systemkatalogtabellen (PG) und andere Amazon Redshift Redshift-Systemtabellen (STLundSTV) sind nicht in einer Transaktion gesperrt. Daher sind Änderungen an Datenbankobjekten, die sich aus DDL TRUNCATE Vorgängen ergeben, bei der Übertragung für alle gleichzeitigen Transaktionen sichtbar.

Angenommen, Tabelle A ist in der Datenbank vorhanden, wenn zwei gleichzeitige Transaktionen, T1 und T2, gestartet werden. Nehmen wir an, T2 gibt eine Liste von Tabellen zurück, indem es aus der TABLES PG_-Katalogtabelle auswählt. Dann löscht T1 Tabelle A und Commits, und dann listet T2 die Tabellen erneut auf. Tabelle A ist jetzt nicht mehr aufgeführt. Wenn T2 versucht, eine Abfrage für die entfernte Tabelle auszuführen, gibt Amazon Redshift den Fehler „Beziehung nicht vorhanden“ zurück. Die Katalogabfrage, die die Liste von Tabellen an T2 zurückgibt oder überprüft, ob Tabelle A vorhanden ist, unterliegt nicht denselben Isolierungsregeln wie Operationen in Benutzertabellen.

Transaktionen für Aktualisierungen dieser Tabellen werden im Isolierungsmodus read committed ausgeführt. PG-prefix-Katalogtabellen unterstützen die Snapshot-Isolierung nicht.

Serialisierbare Isolierung für Systemtabellen und Katalogtabellen

Ein Datenbank-Snapshot wird auch in einer Transaktion für jede SELECT Abfrage erstellt, die auf eine vom Benutzer erstellte Tabelle oder eine Amazon Redshift Redshift-Systemtabelle (STLoderSTV) verweist. SELECTAbfragen, die auf keine Tabelle verweisen, erstellen keinen neuen Transaktionsdatenbank-Snapshot. INSERTDELETE, und UPDATE Anweisungen, die ausschließlich auf Systemkatalogtabellen (PG) basieren, erstellen auch keinen neuen Transaktionsdatenbank-Snapshot.

Beheben von Fehlern für die serialisierbare Isolierung

ERROR:1023DETAIL: Serialisierbare Isolationsverletzung für eine Tabelle in Redshift

Wenn Amazon Redshift einen Fehler für die serialisierbare Isolierung erkennt, wird Ihnen eine Fehlermeldung ähnlich der folgenden Fehlermeldung angezeigt.

ERROR:1023 DETAIL: Serializable isolation violation on table in Redshift

Um einen Fehler für die serialisierbare Isolierung zu beheben, können Sie die folgenden Methoden anwenden:

  • Wiederholen der abgebrochenen Transaktion.

    Amazon Redshift hat festgestellt, dass ein gleichzeitiger Workload nicht serialisierbar ist. Dies weist auf Lücken in der Anwendungslogik hin, die normalerweise bearbeitet werden können, indem die Transaktion erneut versucht wird, bei der der Fehler aufgetreten ist. Wenn das Problem weiterhin besteht, wenden Sie eine der anderen Methoden an.

  • Verschieben Sie alle Operationen, die sich nicht in derselben atomaren Transaktion befinden müssen, aus der Transaktion.

    Diese Methode kann angewendet werden, wenn sich einzelne Operationen innerhalb von zwei Transaktion gegenseitig so referenzieren, dass das Ergebnis der jeweils anderen Transaktion beeinflusst werden kann. Die folgenden beiden Sitzungen starten beispielsweise jeweils eine Transaktion.

    Session1_Redshift=# begin;
    Session2_Redshift=# begin;

    Das Ergebnis einer SELECT Anweisung in jeder Transaktion kann durch eine INSERT Anweisung in der anderen Transaktion beeinflusst werden. Angenommen, Sie führen die folgenden Anweisungen seriell in beliebiger Reihenfolge aus. In jedem Fall ist das Ergebnis eine der SELECT Anweisungen, die eine Zeile mehr zurückgibt, als wenn die Transaktionen gleichzeitig ausgeführt würden. Es gibt keine Reihenfolge, in der die Operationen seriell ausgeführt werden können und zum gleichen Ergebnis wie bei einer gleichzeitigen Ausführung führen. Daher führt die zuletzt ausgeführte Operation zu einem Fehler für die serialisierbare Isolierung.

    Session1_Redshift=# select * from tab1; Session1_Redshift=# insert into tab2 values (1);
    Session2_Redshift=# insert into tab1 values (1); Session2_Redshift=# select * from tab2;

    In vielen Fällen ist das Ergebnis der SELECT Anweisungen nicht wichtig. Mitanderen Worten: Die Atomizität der Operationen in den Transaktionen ist nicht wichtig. In diesen Fällen sollten Sie die SELECT Kontoauszüge außerhalb ihrer Transaktionen platzieren, wie in den folgenden Beispielen gezeigt.

    Session1_Redshift=# begin; Session1_Redshift=# insert into tab1 values (1) Session1_Redshift=# end; Session1_Redshift=# select * from tab2;
    Session2_Redshift # select * from tab1; Session2_Redshift=# begin; Session2_Redshift=# insert into tab2 values (1) Session2_Redshift=# end;

    In diesen Beispielen gibt es keine Querbezüge in den Transaktionen. Die beiden INSERT Aussagen beeinflussen sich nicht gegenseitig. In diesen Beispielen gibt es mindestens eine Reihenfolge, in der die Transaktionen seriell ausgeführt werden können und zum gleichen Ergebnis wie bei einer gleichzeitigen Ausführung führen. Das bedeutet, dass die Transaktionen serialisierbar sind.

  • Sie können die Serialisierung erzwingen, indem Sie alle Tabellen in jeder Sitzung sperren.

    Der Befehl LOCK blockiert Operationen, die zu Fehlern für die serialisierbare Isolierung führen können. Wenn Sie den LOCK Befehl verwenden, achten Sie darauf, Folgendes zu tun:

    • Sperren Sie alle Tabellen, die von der Transaktion betroffen sind, einschließlich der Tabellen, die von schreibgeschützten SELECT Anweisungen innerhalb der Transaktion betroffen sind.

    • Sperren Sie die Tabellen in derselben Reihenfolge, unabhängig von der Reihenfolge, in der die Operationen ausgeführt werden.

    • Sperren Sie alle Tabellen zu Beginn der Transaktion, bevor Operationen ausgeführt werden.

  • Verwenden Sie die Snapshot-Isolation für gleichzeitige Transaktionen

    Verwenden Sie einen ALTER DATABASE Befehl mit Snapshot-Isolation. Weitere Hinweise zum SNAPSHOT Parameter für ALTER DATABASE finden Sie unterParameter.

ERRORDETAILWeitere Hinweise zum Parameter für finden Sie unter. ----sep----:1018: Relation does not exist

Wenn Sie Amazon-Redshift-Vorgänge in verschiedenen Sitzungen ausführen, wird Ihnen eine Fehlermeldung ähnlich der folgenden Fehlermeldung angezeigt.

ERROR: 1018 DETAIL: Relation does not exist.

Transaktionen in Amazon Redshift folgen der Snapshot-Isolation. Nachdem eine Transaktion gestartet wurde, erstellt Amazon Redshift einen Snapshot der Datenbank. Während des gesamten Lebenszyklus der Transaktion arbeitet die Transaktion mit dem Status der Datenbank, wie sie im Snapshot wiedergegeben wird. Wenn die Transaktion aus einer Tabelle liest, die nicht im Snapshot vorhanden ist, wird die zuvor angezeigte Fehlermeldung 1018 ausgelöst. Selbst wenn eine andere gleichzeitige Transaktion eine Tabelle erstellt, nachdem die Transaktion den Snapshot erstellt hat, kann die Transaktion nicht aus der neu erstellten Tabelle lesen.

Um diesen Serialisierungsisolationsfehler zu beheben, können Sie versuchen, den Start der Transaktion an einen Punkt zu verschieben, an dem Sie wissen, dass die Tabelle existiert.

Wenn die Tabelle von einer anderen Transaktion erstellt wird, liegt dieser Punkt nach dem Commit dieser Transaktion. Stellen Sie außerdem sicher, dass gleichzeitig für keine Transaktion ein Commit durchgeführt wurde, das die Tabelle möglicherweise gelöscht hat.

session1 = # BEGIN; session1 = # DROP TABLE A; session1 = # COMMIT;
session2 = # BEGIN;
session3 = # BEGIN; session3 = # CREATE TABLE A (id INT); session3 = # COMMIT;
session2 = # SELECT * FROM A;

Daher führt die zuletzt von session2 als Lesevorgang ausgeführte Operation zu einem serialisierbaren Isolierungsfehler. Dieser Fehler tritt auf, wenn session2 einen Snapshot erstellt und die Tabelle bereits von einer festgeschriebenen session1 gelöscht wurde. Mit anderen Worten, obwohl eine gleichzeitige session3 die Tabelle erstellt hat, sieht session2 die Tabelle nicht, da sie sich nicht im Snapshot befindet.

Um diesen Fehler zu beheben, können Sie die Sitzungen wie folgt neu anordnen.

session1 = # BEGIN; session1 = # DROP TABLE A; session1 = # COMMIT;
session3 = # BEGIN; session3 = # CREATE TABLE A (id INT); session3 = # COMMIT;
session2 = # BEGIN; session2 = # SELECT * FROM A;

Wenn nun session2 seinen Snapshot erstellt, wurde für session3 bereits ein Commit ausgeführt, und die Tabelle befindet sich in der Datenbank. Session2 kann fehlerfrei aus der Tabelle lesen.