Amazon Redshift の分離レベル - Amazon Redshift

Amazon Redshift は、パッチ 198 以降、新しい Python UDF の作成をサポートしなくなります。既存の Python UDF は、2026 年 6 月 30 日まで引き続き機能します。詳細については、ブログ記事を参照してください。

Amazon Redshift の分離レベル

Amazon Redshift では、同時書き込みオペレーションはテーブルの書き込みロックと直列化分離を利用して安全にサポートされます。直列化分離では、テーブルに対して実行されるトランザクションは、そのテーブルに対して実行される唯一のトランザクションであるという錯覚が守られます。

Amazon Redshift データベースは、トランザクションの開始時に各オペレーションでデータの最新のコミット済みバージョンまたはスナップショットを使用することにより、同時書き込み操作をサポートします。データベーススナップショットは、ほとんどの SELECT ステートメント、COPY、DELETE、INSERT、UPDATE、TRUNCATE などの DML コマンド、次の DDL コマンドの最初の発生時にトランザクション内で作成されます。

  • ALTER TABLE (列を追加または削除する)

  • CREATE TABLE

  • DROP TABLE

  • TRUNCATE TABLE

他のトランザクションはこのスナップショットを変更できません。つまり、トランザクションは互いに分離されます。同時トランザクションは互いに認識されません。互いの変更を検出できません。

どのトランザクションの同時実行も、それらのトランザクションの直列実行と同じ結果を生成する必要があります。そのようなトランザクションの直列実行で、同じ結果が生成されない場合、直列化可能性を阻害する可能性のあるステートメントを実行するトランザクションが中断され、ロールバックされます。

例えば、ユーザーが T1 と T2 の 2 つの同時トランザクションを実行しようとするとします。T1 と T2 を実行すると、次のシナリオの少なくとも 1 つと同じ結果が生成されます。

  • T1 と T2 がこの順序で連続して実行されます。

  • T2 と T1 がこの順序で連続して実行されます。

Amazon Redshift の分離レベルは、次の問題を防ぎます。

  • ダーティ読み取り - ダーティ読み取りは、トランザクションがコミットされていないデータを読み取ったときに発生します。例えば、トランザクション 1 が行を更新するとします。トランザクション 2 は T1 が更新をコミットする前に、更新された行を読み取ります。T1 が変更をロールバックすると、T2 は Amazon Redshift が存在したことがないと見なすコミットされていない行のデータを読み取ります。

  • 再現不可能な読み取り - 再現不可能な読み取りは、1 つのトランザクションが同じ行を 2 回読み取るが、毎回異なるデータを取得する場合に発生します。例えば、トランザクション 1 が行を読み取るとします。トランザクション 2 は、その行を更新または削除し、更新または削除をコミットします。T1 が行を再読み込みすると、異なる行値を取得するか、行が削除されたことを検出します。

  • ファントム – ファントムは、検索条件に一致するが、最初は表示されない行です。例えば、トランザクション 1 が、その検索条件を満たす行のセットを読み取るとします。トランザクション 2 は、T1 の検索条件に一致する UPDATE ステートメントまたは INSERT ステートメントに新しい行を生成します。T1 が検索ステートメントを再実行すると、別の行セットを取得します。

SNAPSHOT と SERIALIZABLE の分離

SERIALIZABLE と SNAPSHOT は、Amazon Redshift で利用できる、直列化可能な分離レベルです。

SNAPSHOT 分離は、プロビジョニングされたクラスターとサーバーレスワークグループを作成するときのデフォルトの分離レベルであり、SERIALIZABLE 分離よりも大量のデータを短時間で処理できます。

SERIALIZABLE の分離には時間がかかりますが、同時トランザクションにはより厳しい制約を実装します。この分離レベルは、1 つのトランザクションのみをコミットし、直列化可能な分離違反エラーで他のすべての同時トランザクションをキャンセルすることで、書き込みスキューの異常などの問題を防ぎます。

以下は、SNAPSHOT 分離を使用する場合に 2 つの同時書き込み操作を処理する方法のタイムラインの例です。各ユーザーの UPDATE ステートメントは、同じ行を更新しようとする競合がないため、コミットが許可されます。

Time ユーザー 1 アクション ユーザー 2 アクション
1 BEGIN;
2 BEGIN;
3 SELECT * FROM Numbers;

digits
------
0
1
4 SELECT * FROM Numbers;

digits
------
0
1
5 UPDATE Numbers SET digits=0 WHERE digits=1;
6 SELECT * FROM Numbers;

digits
------
0
0
7 COMMIT;
8 Update Numbers SET digits=1 WHERE digits=0;
9 SELECT * FROM Numbers;

digits
------
1
1
10 COMMIT;
11 SELECT * FROM Numbers;

digits
------
1
0
12 SELECT * FROM Numbers;

digits
------
1
0

直列化可能な分離を使用して同じシナリオを実行する場合、Amazon Redshift は直列化可能な分離違反によりユーザー 2 を終了し、エラー 1023 を返します。詳細については、「直列化可能な分離エラーのトラブルシューティング」を参照してください。この場合、ユーザー 1 だけが正常にコミットできます。

考慮事項

Amazon Redshift の分離レベルを使用する場合、以下の点を考慮してください。

  • STV_DB_ISOLATION_LEVEL カタログビューをクエリして、データベースが使用している分離レベルを表示します。詳細については、「STV_DB_ISOLATION_LEVEL」を参照してください。

  • PG_DATABASE_INFO ビューをクエリして、データベースでサポートされている同時トランザクションの数を確認します。詳細については、「PG_DATABASE_INFO」を参照してください。

  • システムカタログテーブル (PG) と他の Amazon Redshift システムテーブルはトランザクション内にロックされません。そのため、DDL および TRUNCATE オペレーションから発生したデータベースオブジェクトに対する変更は、いずれかの同時トランザクションにコミットすることで表示が可能になります。

    例えば、T1 と T2 という 2 つの同時トランザクションが開始するとき、テーブル A がデータベースに存在します。今、T2 が、テーブルのリストを PG_TABLES カタログテーブルから選択して返しているとします。この時、T1 はテーブル A をドロップしてコミットし、その後 T2 はテーブルを再度リストします。この後、テーブル A はリストされることはなくなります。T2 が削除されたテーブルのクエリを試行すると、Amazon Redshift は "関係が存在しない" というエラーを返します。T2 にテーブルのリストを返す、またはテーブル A が存在することをチェックするカタログクエリは、ユーザーテーブルに対し実行されるオペレーションと同じ分離ルールの対象にはなりません。

    これらのテーブルに対する更新のトランザクションはコミット済み読み取り分離モードで実行されます。

  • PG プレフィックスのカタログテーブルは、スナップショットの分離をサポートしていません。