分離レベル(WriteSerializable と Serializable)
Databricks上のDelta Lake特定のテーブルでの並列操作の相互作用を制御する 2 つの分離レベルをサポートしています。
isolationLevel | 説明 |
|---|---|
シリアル化可能 | 最も強力な分離レベル。コミットされた書き込み操作とすべての読み取りがSerializable であることを保証します。一度に 1 つずつ実行すると、表に示されているものと同じ結果が生成される連続シーケンスがある限り、操作は許可されます。書き込み操作の場合、この連続シーケンスはテーブルの履歴に表示される順序と同じです。 |
WriteSerializable (デフォルト) | Serializable よりも弱い分離レベル。書き込み操作(読み取り操作ではない)のみがシリアル化可能であることを保証します。これはスナップショット分離よりも強力です。ほとんどの一般的な操作に対して、データの一貫性と可用性の適切なバランスを提供します。 |
分離レベルを変更するタイミング
ほとんどのワークロードでは、defaultの「書き込み直列化可能」分離レベルを保持します。
WriteSerializable を使用すると、並列挿入の前に起動された DELETE、 UPDATE、または MERGE は、その後に commit できます。挿入からの行は、操作の条件に一致する場合でも影響を受けません。テーブル履歴は依然として挿入を最初にリストするため、テーブルの内容は履歴順序でcommitを再実行した結果と一致しません。例:並列削除と挿入を参照してください。
この結果を許容できないワークロードの場合は、テーブルをシリアル化可能に変更してください。たとえば、DELETEがcommit時に一致するすべての行を削除する必要がある場合、またはダウンストリームプロセスが履歴のcommit順序からテーブルの内容を再構成する場合などです。Serializableを使用すると、後続の操作が競合により失敗するため、再試行する必要があります。
直列化可能性は、並列書き込みのthroughputを低下させます。テーブルを読み取らない追加は、WriteSerializable では決して競合しませんが、Serializable では競合する可能性があります。「行レベルの同時実行性」を参照してください。
分離レベルが読み取りに与える影響
読み取り操作では常にスナップショット分離が使用されます。書き込み分離レベルは、履歴によれば「存在しなかった」テーブルのスナップショットをリーダーが表示できるかどうかを決定します。
- シリアル化可能 : 読者は常に履歴に準拠したテーブルのみを参照します
- WriteSerializable : 読者はDeltaに存在しないテーブルの状態を見ることができます
例: 削除と挿入
長時間実行される削除トランザクションと挿入トランザクションが同時に開始され、バージョンv0を読み取るシナリオを考えてみましょう。挿入トランザクションが最初にコミットされ、バージョンv1が作成されます。その後、削除トランザクションはv2をコミットしようとします。
t0: deleteTxn_START
t1: insertTxn_START
t2: insertTxn_COMMIT(v1)
t3: deleteTxn_COMMIT(v2)
このシナリオでは、 deleteTxn insertTxnによって挿入されたデータを確認せず、削除も行いませんでした。
- シリアル化可能 :
deleteTxnはコミットが許可されていないため、競合が発生します - WriteSerializable : トランザクションを順序付けることができるため、
deleteTxnコミットが許可されます。結果のテーブルの状態は、insertTxndeleteTxn後に発生した場合と同じになるため、挿入された行はテーブルの一部になります。ただし、 Delta履歴には物理的なコミット順序 (v1 のinsertTxnの前に v2 のdeleteTxn) が表示されます。
分離レベルを設定する
独立性レベルを設定するには、 ALTER TABLEコマンドを使用します:
ALTER TABLE <table-name> SET TBLPROPERTIES ('delta.isolationLevel' = <level-name>)
ここで、 <level-name>はSerializableまたはWriteSerializableです。
例:
-- Change from default WriteSerializable to Serializable
ALTER TABLE my_table SET TBLPROPERTIES ('delta.isolationLevel' = 'Serializable')
Delta Lake はいつテーブルを読み取らずにコミットしますか?
これらの条件が満たされている場合、Delta Lake INSERT または追加操作は、commit前にテーブルの状態を読み取りません。
- ロジックは
INSERTSQLロジックまたは追加モードを使用して表現されます - ロジックには、書き込み操作の対象となるテーブルを参照するサブクエリや条件文は含まれません。
他のコミットと同様に、 Delta Lakeトランザクション ログ メタデータを使用してコミット時にテーブル バージョンを検証および解決しますが、テーブルのバージョンは実際には読み取られません。
多くの一般的なパターンでは、 MERGE操作を使用して、テーブル条件に基づいてデータを挿入します。このロジックをINSERTステートメントを使用して書き換えることは可能ですが、条件式がターゲット テーブルの列を参照する場合、これらのステートメントにはMERGEと同じ同時実行制限が適用されます。