Clonare una tabella in Azure Databricks
È possibile creare una copia di una tabella Delta Lake esistente in Azure Databricks in una versione specifica usando il comando clone
. I cloni possono essere profondi o superficiali.
Azure Databricks supporta anche la clonazione di tabelle Parquet e Iceberg. Vedere clonare in modo incrementale le tabelle Parquet e Iceberg in Delta Lake.
Per informazioni dettagliate sull'uso di clone con Unity Catalog, vedere Clone superficiale per le tabelle del Catalogo Unity.
Nota
Databricks consiglia di usare la condivisione Delta per fornire l'accesso in sola lettura alle tabelle in diverse organizzazioni. Si veda Che cos'è Delta Sharing?.
Tipi di clonazione
- Un clone profondo è un clone che copia i dati della tabella di origine nella destinazione del clone in aggiunta ai metadati della tabella esistente. Inoltre, i metadati del flusso vengono clonati in modo tale che un flusso che scrive nella tabella Delta possa essere interrotto nella tabella di origine e continuare nella tabella di destinazione di un clone dal punto in cui si era fermato.
- Un clone superficiale è un clone che non copia i file di dati nella destinazione di clonazione. I metadati della tabella sono equivalenti all'origine. Questi cloni sono più economici da creare.
I metadati clonati includono: schema, informazioni di partizionamento, invarianti, nullabilità. Solo per i cloni profondi, vengono clonati anche i metadati di flusso e COPY INTO. I metadati non clonati sono la descrizione della tabella e metadati di commit definiti dall'utente.
Qual è la semantica delle operazioni di clonazione Delta?
Se si sta lavorando con una tabella Delta registrata nel metastore Hive o con una raccolta di file non registrati nel metastore come tabella, clone ha la semantica seguente:
Importante
In Databricks Runtime 13.3 LTS e versioni successive, le tabelle gestite di Unity Catalog supportano cloni leggeri. La semantica di clonazione per le tabelle del catalogo Unity differisce in modo significativo dalla semantica dei cloni Delta Lake in altri ambienti. Vedere Clone superficiale per le tabelle del Catalogo Unity.
- Le modifiche apportate ai cloni profondi o superficiali influiscono solo sui cloni stessi e non sulla tabella di origine.
- I cloni superficiali fanno riferimento ai file di dati nella directory di origine. Se si esegue
vacuum
nella tabella di origine, i client non possono più leggere i file di dati di riferimento e viene generata unaFileNotFoundException
. In questo caso, l'esecuzione del clone con sostituzione sul clone superficiale ripristina il clone. Se ciò si verifica spesso, è consigliabile usare un clone profondo che non dipende dalla tabella di origine. - I cloni profondi non dipendono dall'origine da cui sono stati clonati, ma sono costosi da creare perché un clone completo copia i dati e i metadati.
- La clonazione con
replace
verso una destinazione che ha già una tabella in quel percorso crea un log Delta se non ne esiste uno. È possibile pulire tutti i dati esistenti eseguendovacuum
. - Per le tabelle Delta esistenti, viene creato un nuovo commit che include i nuovi metadati e i nuovi dati della tabella di origine. Questo nuovo commit è incrementale, vale a dire che solo le nuove modifiche apportate dall'ultimo clone vengono sottoposte a commit nella tabella.
- La clonazione di una tabella non è uguale a
Create Table As Select
oCTAS
. Un clone copia i metadati della tabella di origine oltre ai dati. La clonazione include anche una sintassi più semplice: non è necessario specificare partizionamento, formato, invarianti, nullabilità e così via, poiché sono derivati dalla tabella di origine. - Una tabella clonata ha una cronologia indipendente dalla tabella di origine. Le query di spostamento temporale in una tabella clonata non funzionano con gli stessi input usati nella tabella di origine.
Sintassi di clonazione di esempio
Gli esempi di codice seguenti illustrano la sintassi per la creazione di cloni profondi e superficiali:
SQL
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)
Python
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)
Scala
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
Per informazioni dettagliate sulla sintassi, vedere CREATE TABLE CLONE.
Metriche di clonazione
CLONE
segnala le metriche seguenti come singolo dataframe di riga al termine dell'operazione:
-
source_table_size
: dimensioni della tabella di origine clonata in byte. -
source_num_of_files
: numero di file nella tabella di origine. -
num_removed_files
: Se la tabella viene sostituita, quanti file vengono rimossi dalla tabella corrente? -
num_copied_files
: numero di file copiati dall'origine (0 per cloni superficiali). -
removed_files_size
: dimensioni in byte dei file da rimuovere dalla tabella corrente. -
copied_files_size
: dimensioni in byte dei file copiati nella tabella.
Autorizzazioni
È necessario configurare le autorizzazioni per il controllo di accesso alle tabelle di Azure Databricks e il provider di servizi cloud.
Controllo di accesso alle tabelle
Per i cloni profondi e superficiali sono necessarie le autorizzazioni seguenti:
-
SELECT
autorizzazione per la tabella di origine. - Se si usa
CLONE
per creare una nuova tabella, è necessaria l'autorizzazioneCREATE
sul database in cui si sta creando la tabella. - Se usi
CLONE
per sostituire una tabella, devi avere il permessoMODIFY
sulla tabella.
Autorizzazioni del provider di servizi cloud
Se è stato creato un clone completo, qualsiasi utente che legge il clone profondo deve avere accesso in lettura alla directory del clone. Per apportare modifiche al clone, gli utenti devono avere accesso in scrittura alla directory del clone.
Se è stato creato un clone superficiale, qualsiasi utente che legge il clone superficiale richiede l'autorizzazione per leggere i file nella tabella originale, poiché i file di dati rimangono nella tabella di origine con cloni superficiali, nonché la directory del clone. Per apportare modifiche al clone, gli utenti dovranno accedere in scrittura alla directory del clone.
Usare il clone per l'archiviazione dei dati
È possibile usare la clonazione profonda per mantenere lo stato di una tabella in un determinato momento a scopo di archiviazione. È possibile sincronizzare i cloni profondi in modo incrementale per mantenere lo stato aggiornato di una tabella di origine per il ripristino di emergenza.
-- Every month run
CREATE OR REPLACE TABLE archive_table CLONE my_prod_table
Usare il clone per la riproduzione del modello di Machine Learning
Quando si esegue l'apprendimento automatico, è possibile archiviare una determinata versione di una tabella in cui è stato eseguito il training di un modello di Machine Learning. I modelli futuri possono essere testati usando questo set di dati archiviato.
-- Trained model on version 15 of Delta table
CREATE TABLE model_dataset CLONE entire_dataset VERSION AS OF 15
Usare "clone" per esperimenti a breve termine su una tabella di produzione
Per testare un flusso di lavoro in una tabella di produzione senza danneggiare la tabella, è possibile creare facilmente un clone superficiale. In questo modo è possibile eseguire flussi di lavoro arbitrari nella tabella clonata che contiene tutti i dati di produzione, ma non influisce sui carichi di lavoro di produzione.
-- 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;
Usare clone per eseguire l'override delle proprietà della tabella
Gli override delle proprietà della tabella sono particolarmente utili per:
- Annotazione di tabelle con informazioni sul proprietario o sull'utente durante la condivisione di dati con business unit diverse.
- È necessario archiviare le tabelle delta e la cronologia delle tabelle o viaggi nel tempo. È possibile specificare i periodi di conservazione dei dati e dei log in modo indipendente per la tabella di archiviazione. Ad esempio:
SQL
CREATE OR REPLACE TABLE archive_table CLONE prod.my_table
TBLPROPERTIES (
delta.logRetentionDuration = '3650 days',
delta.deletedFileRetentionDuration = '3650 days'
)
Python
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
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)