行レベルのコンカレンシーは、行レベルで変更を検出し、同時書き込みが同じデータ ファイル内の異なる行を更新または削除したときに発生する競合を自動的に解決することで、同時書き込み操作間の競合を軽減します。
行レベルのコンカレンシーの要件
テーブルにパーティションが定義されているか、削除ベクターが有効になっていない場合、テーブルは行レベルのコンカレンシーをサポートしません。 行レベルのコンカレンシーには、Databricks Runtime 14.2 以降が必要です。
パーティションを持つテーブルは行レベルのコンカレンシーをサポートしていませんが、削除ベクトルが有効になっている場合でも、 OPTIMIZE とその他のすべての書き込み操作の競合を回避できます。 「行レベルのコンカレンシーの制限事項」を参照してください。
14.2 より前の Databricks ランタイム バージョンについては、「 行レベルのコンカレンシー プレビューの動作 (レガシ)」を参照してください。
注
Databricks Runtime 14.2 では、MERGE INTO での行レベル コンカレンシーのサポートには、Photon が必要です。 Databricks Runtime 14.3 LTS 以降では Photon は必要ありません。
同時実行性における行レベルの競合行列
次の表は、行レベルのコンカレンシーが有効になっている各分離レベルで競合する書き込み操作のペアを示しています。
| INSERT (1) | UPDATE、DELETE、MERGE INTO | OPTIMIZE | |
|---|---|---|---|
| INSERT | 競合できない | ||
| UPDATE、DELETE、MERGE INTO | WriteSerializable で競合が発生する可能性はありません。 同じ行を変更するときに Serializable で競合する可能性があります。 | 同じ行を変更すると競合する可能性があります。 | |
| OPTIMIZE | 競合できない |
ZORDER BY を使用すると競合する可能性があります。 それ以外の場合は競合する可能性はありません。 |
ZORDER BY を使用すると競合する可能性があります。 それ以外の場合は競合する可能性はありません。 |
(1) この表のすべての INSERT 操作は、コミット前に同じテーブルからデータを読み取らない追加操作を記述します。 同じテーブルを読み取るサブクエリを含む INSERT 操作では、MERGE と同じコンカレンシーがサポートされます。
注
- ID 列を持つテーブルでは、同時実行トランザクションはサポートされていません。 Delta Lake での ID 列の使用を参照してください。
-
REORG操作には、データ ファイルの書き換え時のOPTIMIZEと同じ分離セマンティクスがあります。REORGを使用してアップグレードを適用する際は、テーブルのプロトコルが変更され、すべての進行中の操作と競合します。
行レベルのコンカレンシーなしでの書き込みの競合
テーブルにパーティションが定義されているか、削除ベクトルが有効になっていない場合、テーブルは行レベル コンカレンシーをサポートしません。 行レベル コンカレンシーには、Databricks Runtime 14.2 以上が必要です。
行レベルのコンカレンシーのない競合マトリックス
次の表は、各分離レベルで競合する可能性がある書き込み操作のペアを示しています。
| INSERT (1) | UPDATE、DELETE、MERGE INTO | OPTIMIZE | |
|---|---|---|---|
| INSERT | 競合できない | ||
| UPDATE、DELETE、MERGE INTO | WriteSerializable で競合が発生する可能性はありません。 Serializable で競合する可能性があります。 パーティション分割を使用した競合の回避を参照してください。 | Serializable と WriteSerializable で競合する可能性がある。 パーティション分割を使用した競合の回避を参照してください。 | |
| OPTIMIZE | 競合できない |
ZORDER BYを使用しない限り、削除ベクトルが有効になっているテーブルで競合することはできません。 それ以外の場合は競合が発生する可能性があります。 |
ZORDER BYを使用しない限り、削除ベクトルが有効になっているテーブルで競合することはできません。 それ以外の場合は競合が発生する可能性があります。 |
(1) この表のすべての INSERT 操作は、コミット前に同じテーブルからデータを読み取らない追加操作を記述します。 同じテーブルを読み取るサブクエリを含む INSERT 操作では、MERGE と同じコンカレンシーがサポートされます。
注
- ID 列を持つテーブルでは、同時実行トランザクションはサポートされていません。 Delta Lake での ID 列の使用を参照してください。
-
REORG操作には、データ ファイルの書き換え時のOPTIMIZEと同じ分離セマンティクスがあります。REORGを使用してアップグレードを適用する際は、テーブルのプロトコルが変更され、すべての進行中の操作と競合します。
行レベルのコンカレンシーの制限事項
行レベルのコンカレンシーには制限が適用されます。 次の操作では、競合の解決は、書き込みの競合に対する通常のコンカレンシーに従います。 「行レベルのコンカレンシーなしでの書き込みの競合」を参照してください。
| 制限事項 | 説明 |
|---|---|
| 複雑な条件句 | 複合データ型 (構造体、配列、マップ)、非決定論的式、サブクエリ、および相関サブクエリの条件 |
MERGE 述語の要件 |
Databricks Runtime 14.2 では、 MERGE コマンドはターゲット テーブルの明示的な述語を使用して、ソース テーブルに一致する行をフィルター処理する必要があります |
| パフォーマンスのトレードオフ | 行レベルの競合検出では、合計実行時間が長くなる可能性があります。 同時実行トランザクションが多数ある場合、ライターは競合の解決よりも待機時間を優先します |
削除ベクトルのすべての制限事項もあてはまります。 制限事項を参照してください。
パーティション分割を使用して競合を回避する
競合マトリックスで "競合する可能性があります" とマークされているすべてのケースで、2 つの操作が同じファイル セットに影響を与える場合にのみ競合が発生します。 2 つのファイル セットを不整合にするには、操作条件で使用されるのと同じ列でテーブルをパーティション分割します。
Example:
テーブルが日付でパーティション分割されていない場合、コマンドUPDATE table WHERE date > '2010-01-01' ...DELETE table WHERE date < '2010-01-01'競合します。これは、両方が同じファイルを変更しようとする可能性があるためです。
dateでテーブルをパーティション分割すると、競合が回避されます。
注
カーディナリティの高い列でテーブルをパーティション分割すると、サブディレクトリの数が多いため、パフォーマンスの問題が発生する可能性があります。
例: 明示的なパーティション フィルターとの競合を回避する
異なるパーティションを更新する場合でも、同時に同じパーティションを読み取る可能性があるDELETE、UPDATE、またはMERGE操作中に、この例外がよくスローされます。 操作条件で分離を明示的にします。
// Problem: Condition can scan the entire table
deltaTable.as("t").merge(
source.as("s"),
"s.user_id = t.user_id AND s.date = t.date AND s.country = t.country")
.whenMatched().updateAll()
.whenNotMatched().insertAll()
.execute()
// Solution: Add explicit partition filters
deltaTable.as("t").merge(
source.as("s"),
"s.user_id = t.user_id AND s.date = t.date AND s.country = t.country AND t.date = '" + date + "' AND t.country = '" + country + "'")
.whenMatched().updateAll()
.whenNotMatched().insertAll()
.execute()
競合の例外
トランザクションの競合が発生すると、次のいずれかの例外が発生します。
コンカレント・アペンドエクセプション (ConcurrentAppendException)
この例外は、同時実行操作によって、操作で読み取られたのと同じパーティション (またはパーティション分割されていないテーブル内の任意の場所) にファイルが追加された場合に発生します。
INSERT、DELETE、UPDATE、または MERGE の各操作によってファイルが追加される可能性があります。
既定の WriteSerializable 分離レベルでは、ブラインド INSERT 操作 (データを読み取らずにデータを追加する操作) によって追加されたファイルは、操作と競合しません。 分離レベルがシリアル化可能である場合、非同期追加が競合を引き起こす可能性があります。
Important
複数の同時実行 DELETE、UPDATE、またはMERGE 操作がブラインド付加によって挿入された値を参照する可能性がある場合、WriteSerializable モードではブラインド付加が競合する可能性があります。 これを回避するには、次のようにします。
- 同時実行
DELETE、UPDATE、またはMERGE操作が追加されたデータを読み取らないようにする - 追加されたデータを読み取ることができる最大 1 つの
DELETE、UPDATE、またはMERGE操作がある
ConcurrentDeleteReadException
この例外は、同時実行操作が操作で読み取ったファイルを削除するときに発生します。 一般的な原因は、ファイルを書き換える DELETE、 UPDATE、または MERGE 操作です。
ConcurrentDeleteDeleteException
あなたの操作によって削除されるファイルが、同時に他の操作によっても削除されると、この例外が発生します。 これは、同じファイルを書き換える 2 つの同時実行圧縮操作によって発生する可能性があります。
MetadataChangedException
この例外は、同時実行トランザクションによって Delta テーブルのメタデータが更新されると発生します。 一般的な原因は、テーブル スキーマを更新する ALTER TABLE 操作または書き込みです。
同時トランザクション例外
この例外は、同じチェックポイントの場所を使用するストリーミング クエリが複数回同時に開始され、同時に Delta テーブルへの書き込みを試みる場合に発生します。 同じチェックポイントの場所で 2 つのストリーミング クエリを同時に実行しないでください。
プロトコルチェンジドエクセプション (ProtocolChangedException)
この例外は、次の場合に発生する可能性があります。
- Delta テーブルが新しいプロトコル バージョンにアップグレードされます (Databricks ランタイムのアップグレードが必要になる場合があります)
- 複数のライターが同時にテーブルを作成または置き換える
- 複数の執筆者が空のパスに同時に書き込んでいます
Delta Lake の機能の互換性とプロトコルに関する記事を参照してください。
行レベル コンカレンシー プレビューの動作 (レガシ)
このセクションでは、Databricks Runtime 14.1 以下での行レベル コンカレンシーのプレビュー動作について説明します。
| Databricks Runtime のバージョン | 行動 |
|---|---|
| Databricks Runtime 13.3 LTS 以降 | 液体クラスタリングを使用するテーブルで行レベルのコンカレンシーが自動的に有効になります |
| Databricks Runtime 14.0 および 14.1 | 以下の構成を使用して、削除ベクターを含むテーブルの行レベルのコンカレンシーを有効にする |
| Databricks Runtime 14.1 以下 | 非 Photon コンピューティングでは、 DELETE 操作の行レベルのコンカレンシーのみがサポートされます |
Databricks Runtime 14.0 および 14.1 で行レベルのコンカレンシーを有効にするには:
spark.databricks.delta.rowLevelConcurrencyPreview = true
行レベル コンカレンシーには、常に削除ベクトルが必要です。