メインコンテンツまでスキップ

行レベルの同時実行

行レベルの同時実行性は、行レベルでの変更を検出し、並列書き込みによって同じデータ ファイル内の異なる行が更新または削除されるときに発生する競合を自動的に解決することで、並列書き込み操作間の競合を軽減します。

行レベルの同時実行の要件

行レベルの同時実行性は、以下のすべての要件が満たされた場合に自動的に有効になります。

  • Databricks Runtime 14.3 LTS 以降を使用します。
  • ソーステーブルはパーティションを使用しません。
  • ソーステーブルは削除ベクトルが有効になっています。「Databricks の削除ベクトル」を参照してください。

パーティション分割されたテーブルは行レベルの同時実行性をサポートしていません。ただし、削除ベクトルが有効になっている場合、パーティションを持つテーブルはOPTIMIZEと書き込み操作との競合を回避できます。行レベルの同時実行性の制限を参照してください。

14.3 LTS より前の Databricks Runtime バージョンについては、「行レベルのコンカレンシーのレガシー動作」を参照してください。

行レベルの同時実行による競合マトリックス

行レベルの同時実行が有効なソーステーブルでは、次の表は、各分離レベルで競合する可能性のある書き込み操作のペアを示しています。

オペレーション

挿入(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を使用してアップグレードを適用すると、テーブル プロトコルが変更され、進行中のすべての操作と競合します。

行レベルの同時実行性のない書き込みの競合

行レベルの同時実行がないソーステーブルでは、次の表は、各独立性レベルで競合する可能性がある書き込み操作のペアを示しています。

オペレーション

挿入(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 セットのファイルを分離するには、操作条件で使用される同じ列でテーブルをパーティション分割します。

例:

テーブルが日付でパーティション分割されていない場合、コマンドUPDATE table WHERE date > '2010-01-01' ...DELETE table WHERE date < '2010-01-01'は両方とも同じファイルを変更しようとするため、競合します。テーブルをdateでパーティション分割すると競合を回避できます。

注記

カーディナリティの高い列でテーブルをパーティション分割すると、サブディレクトリの数が多くなり、パフォーマンスの問題が発生する可能性があります。

明示的なパーティションフィルターとの競合を避ける

この例外は、異なるパーティションを更新している場合でも、同じパーティションを読み取る可能性がある並列のDELETEUPDATE、またはMERGE操作中に頻繁に発生します。操作条件で分離を明確にしてください:

Scala
// 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

この例外は、並列操作によって、操作が読み取るのと同じパーティション (またはパーティション化されていないテーブル内の任意の場所) にファイルが追加されたときに発生します。 ファイルの追加は、 INSERTDELETEUPDATE 、またはMERGE操作によって発生する可能性があります。

デフォルトのWriteSerializable分離レベルでは、データを読み取ることなくデータを追加するINSERTのオペレーションによって追加されたファイルは、いずれのオペレーションとも競合しません。分離レベルが直列化可能な場合、追記によって競合が発生する可能性があります。

重要

INSERT WriteSerializable モードでは、複数の並列DELETEUPDATE、またはMERGEオペレーションがINSERTオペレーションによって追加された値を参照する可能性がある場合、オペレーションが競合する可能性があります。これを回避するには:

  • 並列の DELETEUPDATE、または MERGE オペレーションによって、追加されたデータが読み込まれないようにしてください。
  • 追加されたデータを読み取ることができるDELETEUPDATE 、またはMERGE操作が最大 1 つあります

ConcurrentDeleteReadException

この例外は、並列操作によって、操作で読み取ったファイルが削除されたときに発生します。 一般的な原因は、ファイルを書き換えるDELETEUPDATE 、またはMERGE操作です。

ConcurrentDeleteDeleteException

この例外は、並列操作によって、ユーザーの操作によっても削除されるファイルが削除された場合に発生します。 これは、同じファイルを書き換える 2 つの並列圧縮操作によって発生する可能性があります。

MetadataChangedException

この例外は、並列トランザクションがDeltaテーブルのメタデータを更新したときに発生します。 一般的な原因は、テーブル スキーマを更新するALTER TABLE操作または書き込みです。

ConcurrentTransactionException

この例外は、同じチェックポイントの場所を使用するストリーミング クエリが同時に複数回開始され、同時に Delta テーブルに書き込もうとした場合に発生します。同じチェックポイントの場所を持つ 2 つのストリーミング クエリを同時に実行しないでください。

ProtocolChangedException

この例外は次の場合に発生する可能性があります:

  • Delta Lake テーブルは新しいプロトコルバージョンにアップグレードされます(Databricks Runtime のアップグレードが必要になる場合があります)。
  • 複数のライターが同時にテーブルを作成または置換しています
  • 複数のライターが同時に空のパスに書き込んでいます

Delta Lake 機能の互換性とプロトコルを参照してください。

行レベルのコンカレンシー レガシー動作

Databricks Runtime 13.3 LTS では、行レベルのコンカレンシーはレガシー動作を使用します。

  • 削除ベクトルが必要です。「Databricks の削除ベクトル」を参照してください。
  • リキッドクラスタリングが有効になっているテーブルでは、行レベルの同時実行性が自動的に有効になります。

次のステップ