利用 CLONE 指令複製 Delta Lake 或 Apache Iceberg 表格,並在特定版本建立獨立副本。 深度複製同時複製資料和元資料。 淺克隆僅複製元資料並參考來源資料檔案,使用較少的運算與儲存空間,而深度克隆則較少。
Azure Databricks 也支持複製 Parquet 和 Apache Iceberg 數據表。 請參閱 以增量方式將 Parquet 和 Apache Iceberg 資料表複製到 Delta Lake和複製受控的 Iceberg 資料表。
如需有關使用 Unity Catalog 的克隆的詳細資訊,請參閱 Unity Catalog 表的淺層克隆。
備註
Databricks 建議使用 OpenSharing 提供跨組織資料表的唯讀存取。 請參閱什麼是開放共享(OpenSharing?)。
複製類型
以下克隆類型可供選擇:
| 類型 | SQL 語法 | Description |
|---|---|---|
| 深層複製人 |
CLONE 或 DEEP CLONE |
將來源資料表的資料與元資料複製到克隆目標,包括串流元資料。 寫入來源資料表的串流可以先停止,之後再從先前停止的位置於複本目標上繼續執行。 |
| 淺層複製 | SHALLOW CLONE |
只將來源資料表的元資料複製到克隆目標。 資料檔案不會被複製。 淺克隆的製作成本較低,因為該操作消耗的運算資源和儲存空間較少。 |
克隆的元資料包括:結構、分割資訊、不變量、空性及 TBLPROPERTIES。 僅在進行深層複製時,數據流和 COPY INTO 元數據也會被複製。 未被複製的元資料包括資料表描述、 使用者自訂提交元資料、Delta Lake 資料表歷史,以及 Unity 目錄屬性(如 標籤)。
克隆指標
CLONE 在作業完成之後,會將下列計量報告為單一數據列 DataFrame:
-
source_table_size:以位元組為單位複製之源數據表的大小。 -
source_num_of_files:源數據表中的檔案數目。 -
num_removed_files:如果要取代數據表,則會從目前的數據表中移除多少個檔案。 -
num_copied_files:從來源複製的檔案數量(如為淺層複製則顯示 0)。 -
removed_files_size:從目前數據表中移除之檔案的位元元組大小。 -
copied_files_size:複製到資料表的檔案大小,以位元組計算。
Permissions
您必須設定 Azure Databricks 資料表存取控制和雲端提供者的許可權。
資料表存取控制
深層和淺層複製需要下列許可權:
-
SELECT源數據表的許可權。 - 如果您使用
CLONE來建立新的資料表,則需要擁有該資料庫的CREATE許可權,才能建立資料表。 - 如果您使用
CLONE來取代數據表,則必須擁有MODIFY數據表的許可權。
雲端提供者許可權
深度複製的讀取器需要對該複製目錄的讀取權限。 寫入者需要對複製目錄的寫入權限。
淺層克隆的讀取器需要同時讀取來源資料表的資料檔案與克隆目錄,因為資料檔案仍保留在原始碼中。 寫入者需要對複製目錄的寫入權限。
Examples
製造深層或淺層克隆
以下程式碼範例示範如何建立深度與淺層克隆:
SQL
建立一個深層複製:
CREATE TABLE target_table CLONE source_table;
替換現有目標:
CREATE OR REPLACE TABLE target_table CLONE source_table;
建立深度複製,或若目標已存在則跳過:
CREATE TABLE IF NOT EXISTS target_table CLONE source_table;
在最新版本、特定版本或特定時間戳下建立淺層克隆。 時間戳可以是日期 '2019-01-01' 字串,也可以是表達式,例如 date_sub(current_date(), 1)。
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;
Python
Python DeltaTable API 是專屬於 Delta Lake 的。
複製最新版本的原始碼:
from delta.tables import *
deltaTable = DeltaTable.forName(spark, "source_table")
deltaTable.clone(target="target_table", isShallow=True, replace=False)
在特定版本複製原始碼:
deltaTable.cloneAtVersion(version=1, target="target_table", isShallow=True, replace=False)
在特定時間戳記複製來源:
deltaTable.cloneAtTimestamp(timestamp="2019-01-01", target="target_table", isShallow=True, replace=False)
Scala
Scala DeltaTable API 是專屬於 Delta Lake 的。
複製最新版本的原始碼:
import io.delta.tables._
val deltaTable = DeltaTable.forName(spark, "source_table")
deltaTable.clone(target="target_table", isShallow=true, replace=false)
在特定版本複製原始碼:
deltaTable.cloneAtVersion(version=1, target="target_table", isShallow=true, replace=false)
在特定時間戳記複製來源:
deltaTable.cloneAtTimestamp(timestamp="2019-01-01", target="target_table", isShallow=true, replace=false)
如需語法詳細數據,請參閱 CREATE TABLE CLONE。
檢查複製期間的元資料 CLONE
這個範例顯示在 CLONE 作業期間哪些中繼資料會與不會被複製,具體來說包括 TBLPROPERTIES、Unity Catalog 標籤,以及 Delta Lake 歷程記錄。
建立一個帶有自訂屬性且日誌保留時間非預設的來源資料表,然後插入資料以產生資料表歷史:
CREATE OR REPLACE TABLE test_clone_source (id INT, val STRING)
TBLPROPERTIES ('my.custom.prop' = 'hello', 'delta.logRetentionDuration' = '12 days');
ALTER TABLE test_clone_source SET TAGS ('team' = 'data-eng', 'env' = 'prod');
INSERT INTO test_clone_source VALUES (1, 'a');
INSERT INTO test_clone_source VALUES (2, 'b');
製作一個深層克隆和一個淺克隆:
CREATE OR REPLACE TABLE test_clone_deep DEEP CLONE test_clone_source;
CREATE TABLE test_clone_shallow SHALLOW CLONE test_clone_source;
備註
在 Unity Catalog 中,你無法用 CREATE OR REPLACE 來覆蓋現有的淺層複製。 請使用 DROP TABLE 後接 CREATE TABLE,或使用新的表格名稱。 請參閱限制。
確認 TBLPROPERTIES 已複製到兩個複本:
SHOW TBLPROPERTIES test_clone_source;
SHOW TBLPROPERTIES test_clone_deep;
SHOW TBLPROPERTIES test_clone_shallow;
確認 Unity 目錄標籤沒有被複製到複製品上:
SELECT catalog_name, schema_name, table_name, tag_name, tag_value FROM information_schema.table_tags WHERE table_name = 'test_clone_source';
SELECT catalog_name, schema_name, table_name, tag_name, tag_value FROM information_schema.table_tags WHERE table_name = 'test_clone_deep';
SELECT catalog_name, schema_name, table_name, tag_name, tag_value FROM information_schema.table_tags WHERE table_name = 'test_clone_shallow';
確認三角洲湖的歷史沒有被複製到複製人身上:
DESCRIBE HISTORY test_clone_source;
DESCRIBE HISTORY test_clone_deep;
DESCRIBE HISTORY test_clone_shallow;
清理:
DROP TABLE IF EXISTS test_clone_shallow;
DROP TABLE IF EXISTS test_clone_source;
DROP TABLE IF EXISTS test_clone_deep;
資料封存
您可以使用深層複製來保留某個時間點的數據表狀態,以供封存之用。 您可以逐步同步深層複製,以維持來源資料表的更新後狀態以進行災難復原。
每月執行以下指令以同步壓縮檔:
CREATE OR REPLACE TABLE archive_table CLONE my_prod_table
ML 模型再現
在機器學習的應用情境中,你可能想存檔一個用來訓練機器學習模型的資料表版本。 未來的模型可以使用這個存檔資料集進行測試。 要歸檔包含 CLONE的資料集版本,請執行以下操作:
例如,若要將用於訓練模型的資料表第 15 版歸檔:
CREATE TABLE model_dataset CLONE entire_dataset VERSION AS OF 15
生產工作台上的短期實驗
若想在生產資料表上測試工作流程而不破壞資料表,請建立一個淺層克隆。 淺克隆允許你在克隆資料表上執行工作負載,該資料表會參考所有生產資料,但不會影響任何生產工作負載。
建立一個淺層的生產表克隆:
CREATE TABLE my_test SHALLOW CLONE my_prod_table;
備註
在 Unity Catalog 中,你無法用 CREATE OR REPLACE 來覆蓋現有的淺層複製。 請使用 DROP TABLE 後接 CREATE TABLE,或使用新的表格名稱。 請參閱限制。
對克隆執行更新與驗證:
UPDATE my_test WHERE user_id is null SET invalid=true;
準備好後,將變更合併回去。 合併時會利用複製中的更新資訊,盡可能只修剪變更過的檔案:
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;
覆寫表屬性
表格屬性的覆寫設定可用於:
- 在與不同業務單位共享數據時,以擁有者或使用者資訊標註數據表。
- 當你需要在檔案庫中進行時間旅行時,將三角洲湖的表格歸檔。 你可以獨立指定歸檔表的資料和日誌保留期間。 例如:
SQL
關於三角洲湖的表格:
CREATE OR REPLACE TABLE archive_table CLONE prod.my_table
TBLPROPERTIES (
delta.logRetentionDuration = '3650 days',
delta.deletedFileRetentionDuration = '3650 days'
)
對於 Iceberg 資料表:
CREATE OR REPLACE TABLE archive_table CLONE prod.my_table
TBLPROPERTIES (
iceberg.logRetentionDuration = '3650 days',
iceberg.deletedFileRetentionDuration = '3650 days'
)
Python
Python DeltaTable API 是專為 Delta Lake 設計的。
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)
Scala
Scala DeltaTable API 是針對 Delta Lake 專屬的。
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)
舊版 Hive metastore 的複製作業行為
Important
在 Databricks Runtime 13.3 LTS 及以上版本中,Unity Catalog 管理的資料表支援淺層克隆。 Unity 目錄資料表的複製行為與其他環境中的複製行為不同。 請參閱Unity Catalog 資料表的淺層複製。
對於已註冊至 Hive metastore 的 Delta Lake 資料表,或未註冊為資料表的檔案集合,clone 具有下列行為:
- 對深度或淺層克隆的更改不會影響來源表。
- 淺層複本會引用來源目錄中的數據檔案。 如果你在來源資料表上執行
VACUUM,客戶端就無法再讀取那些資料檔案,這會產生一個FileNotFoundException。 若要修復,請在淺層複本上使用replace執行 clone。 如果這種情況經常發生,可以考慮使用深度克隆,這不依賴來源資料表。 - 深度克隆不依賴來源資料表,但因為複製資料和元資料,建立成本很高。
- 將
replace複製到目標時,如果該路徑上已經有資料表,且 Delta 日誌尚不存在,則會建立 Delta 日誌。 執行VACUUM以清理現有資料。 - 對於現有的 Delta Lake 資料表,複製會建立新的增量提交,僅包含來源資料表自上次複製以來新增的中繼資料與資料。
- 複製資料表不同於
Create Table As Select(CTAS)。 克隆機除了複製資料外,還會複製來源資料表的元資料。 你不需要指定分割、格式、不變性、空檔或其他設定。 - 複製的數據表具有其源數據表的獨立歷程記錄。 在複製資料表上執行時間旅行查詢時,無法使用與來源資料表相同的輸入。