複数のセッションで Amazon Redshift の操作を同時に実行すると、エラー "Serializable isolation violation on table" または "Relation does not exist" が発生します。
簡単な説明
Amazon Redshift での同時書き込み操作は、トランザクションを順番に実行するために、シリアライズ可能である必要があります。さらに、シリアル実行の結果では、トランザクションが同時に実行された場合と同じ結果が得られる必要があります。詳細については、「シリアライズ可能な分離」を参照してください。
解決策
次のいずれかの方法でシリアライザブル分離エラーを解決します。
キャンセルされたトランザクションを再試行する
Amazon Redshift が同時ワークロードをシリアル化できないことを検出した場合、アプリケーションロジックに不整合が生じている可能性があります。エラーの原因となった、キャンセルされたトランザクションを再試行します。
中間コミットを使用する
コミットまたはロールバックが発生すると、トランザクションは完了します。テーブルからの削除操作が実行される前にトランザクションのコミットが発生した場合、新しいトランザクションが作成され、シリアライザブル分離は維持されます。
次の例では、中間 COMMIT コマンドを使用しています。
DELETE FROM XXXXX WHERE date = XXXXX';
→COMMIT;
BEGIN TRANSACTION;
DELETE FROM XXXXX WHERE date = XXXXX';
非アトミック操作をトランザクションの外に移動する
2 つのトランザクション内の個々の操作が相互参照を行っており、もう一方のトランザクションの結果が影響を受ける場合は、この方法を使用します。
結果を他の操作と連動させる必要がない場合は、SELECT ステートメントをトランザクションの外に移動します。
次の例では、SELECT ステートメントをトランザクションの外に移動しています。
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;
上記のトランザクションはシリアライズ可能です。トランザクションを順番に実行しても、結果は同時に実行したときと同じになります。
各セッションですべてのテーブルをロックしてシリアライズを強制する
LOCK コマンドは、シリアライザブル分離エラーを引き起こす可能性のある操作をブロックします。LOCK コマンドを実行する際、次の手順を実行します。
- トランザクションの影響を受けるすべてのテーブルをロックし、トランザクション内の読み取り専用 SELECT ステートメントの影響を受けるテーブルを含めます。
- 操作が実行される順序に関係なく、テーブルを同じ順序でロックします。
- 操作を実行する前に、トランザクションの開始時にすべてのテーブルをロックします。
同時実行トランザクションでスナップショット分離を使用する
シリアライズ可能な分離は厳密なシリアライズを実施します。Amazon Redshift が同時に実行されているトランザクションのシリアル順序に結果をマッピングできない場合、トランザクションが失敗することがあります。
スナップショット分離により同時実行性が向上するため、同じテーブル内の別々の行への同時変更が正常に完了します。
トランザクションは、データベースの最新のコミットバージョン (スナップショット) で実行を継続します。
データベースでスナップショット分離を設定し、CREATE DATABASE コマンドまたは ALTER DATABASE コマンドで ISOLATION LEVEL パラメータを指定します。
データベースが使用している同時実行モデルを確認するには、次のクエリ STV_DB_ISOLATION_LEVEL を実行します。
SELECT * FROM stv_db_isolation_level;
The database can then be altered to SNAPSHOT ISOLATION:
ALTER DATABASE sampledb ISOLATION LEVEL SNAPSHOT;
データベースの分離レベルを変更する際、次のベストプラクティスを実施してください。
- データベース分離レベルを変更するには、スーパーユーザーまたは CREATE DATABASE 権限が必要です。
- データベース環境の分離レベルは変更できません。
- トランザクションブロック内の分離レベルは変更できません。
- 他のユーザーがデータベースに接続している場合、分離レベルの変更コマンドは失敗します。
- 分離レベルの変更コマンドにより、現在のセッションの分離レベル設定が変更される場合があります。
詳細については、「シリアライザブル分離エラーの修正方法」を参照してください。
関連情報
ERROR:1023 DETAIL: Serializable isolation violation on a table in Redshift (Redshift のテーブルでのシリアライザブル分離違反)
ERROR:1018 DETAIL: Relation does not exist
同時書き込み操作を管理する