Beheben von Fehlern für die serialisierbare Isolierung - Amazon Redshift

Amazon Redshift unterstützt ab dem 1. November 2025 nicht mehr die Erstellung neuer Python-UDFs. Wenn Sie Python-UDFs verwenden möchten, erstellen Sie die UDFs vor diesem Datum. Bestehende Python-UDFs funktionieren weiterhin wie gewohnt. Weitere Informationen finden Sie im Blog-Posting.

Beheben von Fehlern für die serialisierbare Isolierung

FEHLER: 1023 DETAIL: 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 einer der beiden Transaktionen könnte durch eine INSERT-Anweisung in der jeweils anderen Transaktion beeinflusst werden. Angenommen, Sie führen die folgenden Anweisungen seriell in beliebiger Reihenfolge aus. In jedem Fall besteht das Ergebnis darin, dass eine der SELECT-Anweisungen eine Zeile mehr zurückgibt, als dies bei einer gleichzeitigen Ausführung der Transaktionen der Fall wäre. 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 verschieben Sie die SELECT-Anweisungen aus den Transaktionen 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-Anweisungen 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 Befehl LOCK verwenden, müssen Sie Folgendes ausführen:

    • Sperren Sie alle Tabellen, die von der Transaktion betroffen sind, einschließlich 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 Informationen zum SNAPSHOT-Parameter für ALTER DATABASE finden Sie unter Parameter.

FEHLER: 1018 DETAIL: Beziehung existiert nicht

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.