Résolution des problèmes d’isolation sérialisable - Amazon Redshift

Amazon Redshift ne prendra plus en charge la création de nouvelles fonctions Python définies par l’utilisateur à compter du 1er novembre 2025. Si vous souhaitez utiliser des fonctions Python définies par l’utilisateur, créez-les avant cette date. Les fonctions Python définies par l’utilisateur existantes continueront de fonctionner normalement. Pour plus d’informations, consultez le billet de blog .

Résolution des problèmes d’isolation sérialisable

ERROR:1023 DETAIL : Violation d’isolement sérialisable sur une table dans Redshift

Lorsqu’Amazon Redshift détecte une erreur d’isolement sérialisable, le message d’erreur suivant s’affiche.

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

Pour corriger une erreur d’isolement sérialisable, vous pouvez essayer l’une des méthodes suivantes :

  • Réessayez la transaction annulée.

    Amazon Redshift a détecté qu’une charge de travail simultanée n’est pas sérialisable. Il suggère des lacunes dans la logique de l’application, qui peuvent généralement être contournées en réessayant la transaction qui a rencontré l’erreur. Si le problème persiste, essayez l’une des autres méthodes.

  • Déplacez les opérations qui ne doivent pas se trouver dans la même transaction atomique hors de la transaction.

    Cette méthode s’applique lorsque des opérations individuelles à l’intérieur de deux transactions se comparent entre elles d’une façon pouvant affecter le résultat de l’autre transaction. Par exemple, les deux séances suivantes lancent chacune une transaction.

    Session1_Redshift=# begin;
    Session2_Redshift=# begin;

    Le résultat d’une instruction SELECT dans chaque transaction peut être affecté par une instruction INSERT dans l’autre. En d’autres termes, supposons que vous exécutez les instructions suivantes en série, dans n’importe quel ordre. Dans chaque cas, le résultat est l’une des instructions SELECT renvoyant une ligne de plus que si les transactions avaient été exécutées de manière simultanée. Il n’existe aucun ordre dans lequel les opérations peuvent s’exécuter en série et produire le même résultat que si elles étaient exécutées de manière simultanée. Ainsi, la dernière opération exécutée entraîne une erreur d’isolement sérialisable.

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

    Dans de nombreux cas, le résultat de l’instruction SELECT n’est pas important. En d’autres termes, l’atomicité des opérations dans les transactions n’est pas important. Dans ces cas-là, déplacez les instructions SELECT hors de leurs transactions, comme illustré dans les exemples suivants.

    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;

    Dans ces exemples, il n’y a aucune référence croisée dans les transactions. Les deux instructions INSERT n’ont aucun effet l’une sur l’autre. Dans ces exemples, il existe au moins un ordre dans lequel les transactions peuvent s’exécuter en série et produire le même résultat que si elle étaient exécutées de manière simultanée. Cela signifie que les transactions sont sérialisables.

  • Forcez la sérialisation en verrouillant toutes les tables de chaque séance.

    La commande LOCK bloque les opérations pouvant entraîner des erreurs d’isolement sérialisable. Lorsque vous utilisez la commande LOCK, veillez à procéder comme suit :

    • Verrouillez toutes les tables affectées par la transaction, notamment celles affectées par les instructions SELECT en lecture seule à l’intérieur de la transaction.

    • Verrouillez les tables dans le même ordre, quel que soit l’ordre dans lequel ces opérations sont exécutées.

    • Verrouillez toutes les tables au début de la transaction, avant d’exécuter la moindre opération.

  • Utiliser l’isolation des instantanés pour les transactions simultanées

    Utilisez une commande ALTER DATABASE avec l’isolation des instantanés. Pour plus d’informations sur le paramètre SNAPSHOT pour ALTER DATABASE, consultez Paramètres.

ERROR:1018 DETAIL : La relation n’existe pas

Lorsque vous exécutez des opérations Amazon Redshift simultanément dans différentes séances, un message d’erreur similaire au suivant s’affiche.

ERROR: 1018 DETAIL: Relation does not exist.

Les transactions dans Amazon Redshift suivent l’isolement des instantanés. Lorsqu’une transaction a démarré, Amazon Redshift prend un instantané de la base de données. Pour tout le cycle de vie de la transaction, la transaction est exécutée sur l’état de la base de données tel qu’il est reflété dans l’instantané. Si la transaction effectue la lecture à partir d’une table qui n’existe pas dans l’instantané, elle renvoie le message d’erreur 1018 affiché précédemment. Même lorsqu’une autre transaction simultanée crée une table après que la transaction a pris l’instantané, la transaction ne peut pas effectuer la lecture à partir de la table créée.

Pour corriger cette erreur d’isolement de sérialisation, vous pouvez essayer de faire démarrer la transaction à un moment où vous savez que la table existe.

Si la table est créée par une autre transaction, ce moment commence au moins après que cette transaction a été validée. Assurez-vous également qu’aucune transaction simultanée qui aurait pu supprimer la table n’a été validée.

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

La dernière opération exécutée en tant qu’opération de lecture par session2 entraîne une erreur d’isolement sérialisable. Cette erreur se produit lorsqu’une session2 prend un instantané et que la table a déjà été supprimée par une session1 validée. En d’autres termes, même si une session3 simultanée a créé la table, la session2 ne voit pas la table car elle ne se trouve pas dans l’instantané.

Pour résoudre cette erreur, vous pouvez réorganiser les séances comme suit.

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

Lorsque la session2 prend son instantané, la session3 a déjà été validée et la table se trouve dans la base de données. La session2 peut effectuer la lecture à partir de la table sans aucune erreur.