Databricks でテーブルを複製する
clone
コマンドを使用して、特定のバージョンの Databricks 上の既存の Delta Lake テーブルのコピーを作成できます。クローンは、深いクローンでも浅いクローンでもかまいません。
Databricks では、Parquet テーブルと Iceberg テーブルのクローン作成もサポートされています。 「Parquet テーブルと Iceberg テーブルを Delta Lake に段階的に複製する」を参照してください。
クローンと Unity Catalogの使用の詳細については、Unity Catalog テーブルのシャロークローンを参照してください。
Databricks では、Delta Sharing を使用して、異なる組織間のテーブルへの読み取り専用アクセスを提供することをお勧めします。 「Delta Sharing とは」を参照してください。
クローンの種類
- ディープクローン は、既存のテーブルのメタデータに加えて、ソーステーブルのデータをクローンターゲットにコピーするクローンです。さらに、ストリーム メタデータも複製されるため、Delta テーブルに書き込むストリームをソース テーブルで停止し、中断したところから複製のターゲットで続行できます。
- シャロークローン は、データファイルをクローンターゲットにコピーしないクローンです。テーブルのメタデータはソースと同等です。 これらのクローンは、作成コストが安価です。
クローニングされるメタデータには、スキーマ、パーティション分割情報、不変条件、null 値の許容が含まれます。 ディープクローンの場合のみ、ストリームおよび COPY INTO
メタデータもクローニングされます。 クローニングされないメタデータは、テーブルの説明と ユーザー定義のコミットメタデータです。
クローン操作のセマンティクス Delta どのようなものですか?
DeltaHive metastoreに登録されている テーブル、またはテーブルとして登録されていないファイルのコレクションを使用している場合、clone には次のセマンティクスがあります。
Databricks Runtime 13.3 LTS 以降では、Unity Catalog マネージドテーブルは浅いクローンをサポートしています。Unity Catalog テーブルのクローン セマンティクスは、他の環境の Delta Lake クローン セマンティクスとは大きく異なります。 Unity Catalogテーブルについては、シャロークローンを参照してください。
- ディープクローンまたはシャロークローンに加えられた変更は、クローン自体にのみ影響し、ソーステーブルには影響しません。
- シャロークローンは、ソースディレクトリ内のデータファイルを参照します。 ソース・テーブルで
vacuum
を実行すると、クライアントは参照されるデータ・ファイルを読み取ることができなくなり、FileNotFoundException
がスローされます。 この場合、シャロークローンに対して clone と replace を実行すると、クローンが修復されます。 これが頻繁に発生する場合は、ソーステーブルに依存しないディープクローンを代わりに使用することを検討してください。 - ディープクローンは、クローン元のソースに依存しませんが、ディープクローンはデータとメタデータをコピーするため、作成にコストがかかります。
- そのパスにすでにテーブルがあるターゲットに
replace
を使用してクローニングすると、そのパスに Delta ログが存在しない場合は作成されます。 既存のデータをクリーンアップするには、 を実行しますvacuum
。 - 既存の Delta テーブルの場合、ソース テーブルの新しいメタデータと新しいデータを含む新しいコミットが作成されます。 この新しいコミットは増分であり、最後のクローン以降の新しい変更のみがテーブルにコミットされます。
- テーブルのクローニングは、
Create Table As Select
やCTAS
と同じではありません。 クローンは、データに加えてソーステーブルのメタデータをコピーします。 クローニングの構文も単純で、パーティショニング、フォーマット、不変条件、null 可能性などをソーステーブルから取得するときに指定する必要はありません。 - クローニングされたテーブルには、ソーステーブルから独立した履歴があります。 クローンされたテーブルに対するタイムトラベル クエリは、ソース テーブルと同じ入力では機能しません。
クローン構文の例
次のコード例は、ディープクローンとシャロークローンを作成するための構文を示しています。
- SQL
- Python
- Scala
CREATE TABLE target_table CLONE source_table; -- Create a deep clone of source_table as target_table
CREATE OR REPLACE TABLE target_table CLONE source_table; -- Replace the target
CREATE TABLE IF NOT EXISTS target_table CLONE source_table; -- No-op if the target table exists
CREATE TABLE target_table SHALLOW CLONE source_table;
CREATE TABLE target_table SHALLOW CLONE source_table VERSION AS OF version;
CREATE TABLE target_table SHALLOW CLONE source_table TIMESTAMP AS OF timestamp_expression; -- timestamp can be like “2019-01-01” or like date_sub(current_date(), 1)
from delta.tables import *
deltaTable = DeltaTable.forName(spark, "source_table")
deltaTable.clone(target="target_table", isShallow=True, replace=False) # clone the source at latest version
deltaTable.cloneAtVersion(version=1, target="target_table", isShallow=True, replace=False) # clone the source at a specific version
# clone the source at a specific timestamp such as timestamp="2019-01-01"
deltaTable.cloneAtTimestamp(timestamp="2019-01-01", target="target_table", isShallow=True, replace=False)
import io.delta.tables._
val deltaTable = DeltaTable.forName(spark, "source_table")
deltaTable.clone(target="target_table", isShallow=true, replace=false) // clone the source at latest version
deltaTable.cloneAtVersion(version=1, target="target_table", isShallow=true, replace=false) // clone the source at a specific version
deltaTable.cloneAtTimestamp(timestamp="2019-01-01", target="target_table", isShallow=true, replace=false) // clone the source at a specific timestamp
構文の詳細については、 CREATE TABLE CLONEを参照してください。
メトリクスのクローン作成
CLONE
オペレーションが完了すると、次のメトリクスを単一行のデータフレームとしてレポートします:
source_table_size
: クローニングされるソーステーブルのサイズ (バイト単位)。source_num_of_files
: ソース テーブル内のファイルの数。num_removed_files
: テーブルを置き換える場合、現在のテーブルから削除されるファイルの数。num_copied_files
: ソースからコピーされたファイルの数 (浅いクローンの場合は 0)。removed_files_size
: 現在のテーブルから削除されるファイルのサイズ (バイト単位)。copied_files_size
: テーブルにコピーされたファイルのサイズ (バイト単位)。
権限
Databricks テーブルアクセスコントロールとクラウドプロバイダーの権限を設定する必要があります。
テーブルアクセスコントロール
ディープ・クローンとシャロー・クローンの両方に、次の権限が必要です。
SELECT
ソース テーブルに対するアクセス許可。CLONE
を使用して新しいテーブルを作成する場合は、テーブルを作成するデータベースに対するパーミッションCREATE
。CLONE
を使用してテーブルを置き換える場合は、テーブルに対するMODIFY
パーミッションが必要です。
クラウドプロバイダーの権限
ディープクローンを作成した場合、ディープクローンを読み取るすべてのユーザーは、クローンのディレクトリへの読み取りアクセス権を持っている必要があります。 クローンを変更するには、ユーザーはクローンのディレクトリへの書き込み権限を持っている必要があります。
シャロークローンを作成した場合、シャロークローンを読み取るすべてのユーザーには、元のテーブルのファイルを読み取るパーミッションが必要です。これは、データ・ファイルがシャロー・クローンのソース・テーブルとクローンのディレクトリに残っているためです。 クローンに変更を加えるには、クローンのディレクトリへの書き込みアクセス権が必要です。
クローンをデータ・アーカイブに使用する
ディープクローンを使用すると、アーカイブ目的で特定の時点でのテーブルの状態を保持できます。 ディープクローンを増分的に同期して、ディザスタリカバリのためにソーステーブルの更新された状態を維持できます。
-- Every month run
CREATE OR REPLACE TABLE archive_table CLONE my_prod_table
ML モデルの再現にクローンを使用する
機械学習を行うときに、ML モデルをトレーニングしたテーブルの特定のバージョンをアーカイブしたい場合があります。 このアーカイブされたデータセットを使用して、将来のモデルをテストできます。
-- Trained model on version 15 of Delta table
CREATE TABLE model_dataset CLONE entire_dataset VERSION AS OF 15
本番運用テーブルでの短期エクスペリメントに clone を使用
本番運用テーブルでワークフローを破損せずにテストするために、シャロークローンを簡単に作成できます。 これにより、すべての本番運用データを含み、本番運用ワークロードに影響を与えないクローンテーブルで任意のワークフローを実行できます。
-- Perform shallow clone
CREATE OR REPLACE TABLE my_test SHALLOW CLONE my_prod_table;
UPDATE my_test WHERE user_id is null SET invalid=true;
-- Run a bunch of validations. Once happy:
-- This should leverage the update information in the clone to prune to only
-- changed files in the clone if possible
MERGE INTO my_prod_table
USING my_test
ON my_test.user_id <=> my_prod_table.user_id
WHEN MATCHED AND my_test.user_id is null THEN UPDATE *;
DROP TABLE my_test;
clone を使用してテーブル プロパティを上書きする
テーブルプロパティのオーバーライドは、特に次の場合に役立ちます。
- 異なるビジネスユニットとデータを共有するときに、所有者またはユーザー情報でテーブルに注釈を付けます。
- Delta テーブルとテーブル履歴またはタイムトラベルのアーカイブが必要です。 アーカイブ・テーブルに対して、データとログの保存期間を個別に指定できます。 例えば:
- SQL
- Python
- Scala
CREATE OR REPLACE TABLE archive_table CLONE prod.my_table
TBLPROPERTIES (
delta.logRetentionDuration = '3650 days',
delta.deletedFileRetentionDuration = '3650 days'
)
dt = DeltaTable.forName(spark, "prod.my_table")
tblProps = {
"delta.logRetentionDuration": "3650 days",
"delta.deletedFileRetentionDuration": "3650 days"
}
dt.clone(target="archive_table", isShallow=False, replace=True, tblProps)
val dt = DeltaTable.forName(spark, "prod.my_table")
val tblProps = Map(
"delta.logRetentionDuration" -> "3650 days",
"delta.deletedFileRetentionDuration" -> "3650 days"
)
dt.clone(target="archive_table", isShallow = false, replace = true, properties = tblProps)