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 clone
comando . 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. Vedere Che cos'è la condivisione Delta?.
Tipi di clonazione
- Un clone completo è un clone che copia i dati della tabella di origine nella destinazione clone oltre ai metadati della tabella esistente. Inoltre, i metadati del flusso vengono clonati in modo che un flusso che scrive nella tabella Delta possa essere arrestato in una tabella di origine e continuato nella destinazione di un clone da dove è stato interrotto.
- 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, valori Null. Per i cloni profondi, vengono clonati anche i metadati COPY INTO e stream. I metadati non clonati sono la descrizione della tabella e i metadati di commit definiti dall'utente.
Qual è la semantica delle operazioni di clonazione Delta?
Se si usa una tabella Delta registrata nel metastore Hive o in una raccolta di file non registrati 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 superficiali. 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 a cui si fa riferimento e viene generata un'eccezioneFileNotFoundException
. In questo caso, l'esecuzione del clone con sostituzione sul clone superficiale ripristina il clone. Se ciò si verifica spesso, è consigliabile usare un clone completo 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 a
replace
una destinazione che dispone già di una tabella in tale percorso crea un log Delta se non ne esiste uno in tale percorso. È 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
Create Table As Select
a 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, valori Null e così via come vengono ricavati 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.
Clonare le metriche
CLONE
segnala le metriche seguenti come singolo dataframe di riga al termine dell'operazione:
source_table_size
: dimensione 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, il numero di file 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 che vengono rimossi 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 a 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,CREATE
l'autorizzazione per il database in cui si sta creando la tabella. - Se si usa
CLONE
per sostituire una tabella, è necessario disporreMODIFY
dell'autorizzazione per la 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 il clone completo 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 in 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 tabelle delta e cronologia tabelle o spostamenti temporali. È 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)