Nota
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare ad accedere o modificare le directory.
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare a modificare le directory.
Per le tabelle Apache Iceberg e Delta Lake, ogni operazione che modifica una tabella crea una nuova versione della tabella. Usa le informazioni sulla cronologia per verificare le operazioni, eseguire il rollback di una tabella o interrogare una tabella in uno specifico momento usando il time travel.
Nota
Databricks non consiglia di usare la cronologia tabelle come soluzione di backup a lungo termine per l'archiviazione dei dati. Usare solo gli ultimi 7 giorni per le operazioni di spostamento temporale, a meno che non siano state impostate sia configurazioni di conservazione dei dati che dei log su un valore maggiore.
Recuperare la cronologia delle tabelle
Eseguire il DESCRIBE HISTORY comando per recuperare informazioni, incluse le operazioni, l'utente e il timestamp per ogni scrittura in una tabella. Le operazioni vengono restituite in ordine cronologico inverso.
La conservazione della cronologia delle tabelle è determinata dall'impostazione della tabella logRetentionDuration, ovvero 30 giorni per impostazione predefinita.
Nota
Lo spostamento cronologico e la cronologia delle tabelle sono controllati da soglie di conservazione diverse. Vedi Viaggi temporali.
DESCRIBE HISTORY table_name -- get the full history of the table
DESCRIBE HISTORY table_name LIMIT 1 -- get the last operation only
Per informazioni dettagliate sulla sintassi di Spark SQL, vedere DESCRIBE HISTORY.
Per informazioni dettagliate sulla sintassi di Scala, Java e Python, vedere la documentazione dell'API Delta Lake.
Esplora cataloghi mostra visivamente la cronologia delle tabelle nella scheda Cronologia .
Schema cronologia
L'output dell'operazione history include le colonne seguenti.
| Column | Tipo | Description |
|---|---|---|
| version | long |
Versione della tabella generata dall'operazione. |
| Marca temporale | timestamp |
Quando è stato effettuato il commit di questa versione. |
| userId | string |
ID dell'utente che ha eseguito l'operazione. |
| userName | string |
Nome dell'utente che ha eseguito l'operazione. |
| operazione | string |
Nome dell'operazione. |
| parametri di operazione | map |
Parametri dell'operazione, ad esempio predicati. |
| attività | struct |
I dettagli del job Lakeflow che ha eseguito l'operazione. Si popola solo per i commit creati da un job Lakeflow. In caso contrario, null. |
| notebook | struct |
Dettagli del notebook di Databricks da cui è stata eseguita l'operazione. Viene popolato solo per i commit creati da un notebook Databricks. In caso contrario, null. |
| clusterId | string |
ID del cluster in cui è stata eseguita l'operazione. |
| leggiVersione | long |
Versione della tabella letta per eseguire l'operazione di scrittura. |
| isolationLevel | string |
Livello di isolamento utilizzato per questa operazione. |
| isBlindAppend | boolean |
Indica se questa operazione ha accodato dati. |
| operationMetrics | map |
Metriche dell'operazione(ad esempio, numero di righe e file modificati). |
| metadati dell'utente | string |
Metadati di commit definiti dall'utente, se specificati. |
+-------+-------------------+------+--------+---------+--------------------+----+--------+---------+-----------+-----------------+-------------+--------------------+
|version| timestamp|userId|userName|operation| operationParameters| job|notebook|clusterId|readVersion| isolationLevel|isBlindAppend| operationMetrics|
+-------+-------------------+------+--------+---------+--------------------+----+--------+---------+-----------+-----------------+-------------+--------------------+
| 5|2019-07-29 14:07:47| ###| ###| DELETE|[predicate -> ["(...|null| ###| ###| 4|WriteSerializable| false|[numTotalRows -> ...|
| 4|2019-07-29 14:07:41| ###| ###| UPDATE|[predicate -> (id...|null| ###| ###| 3|WriteSerializable| false|[numTotalRows -> ...|
| 3|2019-07-29 14:07:29| ###| ###| DELETE|[predicate -> ["(...|null| ###| ###| 2|WriteSerializable| false|[numTotalRows -> ...|
| 2|2019-07-29 14:06:56| ###| ###| UPDATE|[predicate -> (id...|null| ###| ###| 1|WriteSerializable| false|[numTotalRows -> ...|
| 1|2019-07-29 14:04:31| ###| ###| DELETE|[predicate -> ["(...|null| ###| ###| 0|WriteSerializable| false|[numTotalRows -> ...|
| 0|2019-07-29 14:01:40| ###| ###| WRITE|[mode -> ErrorIfE...|null| ###| ###| null|WriteSerializable| true|[numFiles -> 2, n...|
+-------+-------------------+------+--------+---------+--------------------+----+--------+---------+-----------+-----------------+-------------+--------------------+
Nota
- Se si scrive in una tabella usando i metodi seguenti, alcune colonne non sono disponibili:
- Le colonne aggiunte in futuro verranno sempre aggiunte dopo l'ultima colonna.
Informazioni sui partitionBy parametri dell'operazione
Il partitionBy campo nella cronologia tabelle è significativo solo per le operazioni CREATE e OVERWRITE che definiscono o modificano lo schema di partizione di una tabella.
Per le operazioni di accodamento alle tabelle esistenti (APPEND, INSERT, , UPDATEDELETE, MERGE), questo campo potrebbe mostrare una matrice [] vuota o colonne di partizione a seconda del metodo di scrittura usato (.save() vs .saveAsTable()).
Questa incoerenza è un comportamento previsto e non influisce sul modo in cui i dati vengono scritti nelle partizioni. Non è consigliabile usarlo per convalidare le operazioni di accodamento.
Example
Si consideri una tabella partizionata dalla date colonna . Quando si crea la tabella, partitionBy viene popolata:
df.write.format("delta") \
.partitionBy("date") \
.saveAsTable("sales_data")
L'operazione CREATE nella cronologia mostra:
operationParameters: {
"mode": "ErrorIfExists",
"partitionBy": "[\"date\"]"
}
Quando si aggiungono dati a questa tabella, partitionBy viene visualizzata una matrice vuota:
new_df.write.format("delta") \
.mode("append") \
.saveAsTable("sales_data")
L'operazione APPEND mostra:
operationParameters: {
"mode": "Append",
"partitionBy": "[]"
}
È previsto il valore vuoto partitionBy . I dati vengono comunque scritti nelle partizioni corrette in base allo schema di partizione esistente della tabella. Si noti che .save() a un percorso potrebbe mostrare colonne di partizione in questo campo, ma questa differenza è un dettaglio di implementazione e non influisce sul comportamento di scrittura.
Metriche operative
L'operazione history restituisce una raccolta di metriche operative nella mappa delle operationMetrics colonne.
Le tabelle seguenti elencano le definizioni delle chiavi della mappa in base all'operazione.
WRITE, CREATE TABLE AS SELECT, REPLACE TABLE AS SELECT, COPY INTO
Per queste operazioni sono disponibili le metriche seguenti:
| Nome della metrica di misura | Description |
|---|---|
numFiles |
Numero di file scritti. |
numOutputBytes |
Dimensione in byte del contenuto scritto. |
numOutputRows |
Numero di righe scritte. |
STREAMING UPDATE
Per questa operazione sono disponibili le metriche seguenti:
| Nome della metrica di misura | Description |
|---|---|
numAddedFiles |
Numero di file aggiunti. |
numRemovedFiles |
Numero di file rimossi. |
numOutputRows |
Numero di righe scritte. |
numOutputBytes |
Dimensione della scrittura in byte. |
DELETE
Per questa operazione sono disponibili le metriche seguenti:
| Nome della metrica di misura | Description |
|---|---|
numAddedFiles |
Numero di file aggiunti. Non specificato quando vengono eliminate le partizioni della tabella. |
numRemovedFiles |
Numero di file rimossi. |
numDeletedRows |
Numero di righe rimosse. Non specificato quando vengono eliminate le partizioni della tabella. |
numCopiedRows |
Numero di righe copiate nel processo di eliminazione dei file. |
executionTimeMs |
Tempo impiegato per eseguire l'intera operazione. |
scanTimeMs |
Tempo impiegato per analizzare i file e individuare le corrispondenze. |
rewriteTimeMs |
Tempo impiegato per riscrivere i file corrispondenti. |
TRUNCATE
Per questa operazione sono disponibili le metriche seguenti:
| Nome della metrica di misura | Description |
|---|---|
numRemovedFiles |
Numero di file rimossi. |
executionTimeMs |
Tempo impiegato per eseguire l'intera operazione. |
MERGE
Per questa operazione sono disponibili le metriche seguenti:
| Nome della metrica di misura | Description |
|---|---|
numSourceRows |
Numero di righe nel dataframe di origine. |
numTargetRowsInserted |
Numero di righe inserite nella tabella di destinazione. |
numTargetRowsUpdated |
Numero di righe aggiornate nella tabella di destinazione. |
numTargetRowsDeleted |
Numero di righe eliminate nella tabella di destinazione. |
numTargetRowsCopied |
Numero di righe di destinazione copiate. |
numOutputRows |
Numero totale di righe scritte. |
numTargetFilesAdded |
Il numero di file aggiunti al sink (destinazione). |
numTargetFilesRemoved |
Numero dei file rimossi dal sink (destinazione). |
executionTimeMs |
Tempo impiegato per eseguire l'intera operazione. |
scanTimeMs |
Tempo impiegato per analizzare i file e individuare le corrispondenze. |
rewriteTimeMs |
Tempo impiegato per riscrivere i file corrispondenti. |
UPDATE
Per questa operazione sono disponibili le metriche seguenti:
| Nome della metrica di misura | Description |
|---|---|
numAddedFiles |
Numero di file aggiunti. |
numRemovedFiles |
Numero di file rimossi. |
numUpdatedRows |
Numero di righe aggiornate. |
numCopiedRows |
Numero di righe appena copiate nel processo di aggiornamento dei file. |
executionTimeMs |
Tempo impiegato per eseguire l'intera operazione. |
scanTimeMs |
Tempo impiegato per analizzare i file e individuare le corrispondenze. |
rewriteTimeMs |
Tempo impiegato per riscrivere i file corrispondenti. |
FSCK
Per questa operazione sono disponibili le metriche seguenti:
| Nome della metrica di misura | Description |
|---|---|
numRemovedFiles |
Numero di file rimossi. |
CONVERT
Per questa operazione sono disponibili le metriche seguenti:
| Nome della metrica di misura | Description |
|---|---|
numConvertedFiles |
Numero di file Parquet convertiti. |
OPTIMIZE
Per questa operazione sono disponibili le metriche seguenti:
| Nome della metrica di misura | Description |
|---|---|
numAddedFiles |
Numero di file aggiunti. |
numRemovedFiles |
Numero dei file ottimizzati. |
numAddedBytes |
Numero di byte aggiunti dopo l'ottimizzazione della tabella. |
numRemovedBytes |
Il numero di byte rimossi. |
minFileSize |
Dimensioni del file più piccolo dopo l'ottimizzazione della tabella. |
p25FileSize |
La dimensione del file al 25° percentile dopo l'ottimizzazione della tabella. |
p50FileSize |
Dimensioni del file mediano dopo l'ottimizzazione della tabella. |
p75FileSize |
La dimensione del file al 75° percentile dopo l'ottimizzazione della tabella. |
maxFileSize |
Dimensioni del file più grande dopo l'ottimizzazione della tabella. |
CLONE
Per questa operazione sono disponibili le metriche seguenti:
| Nome della metrica di misura | Description |
|---|---|
sourceTableSize |
Dimensioni in byte della tabella di origine nella versione clonata. |
sourceNumOfFiles |
Numero di file nella tabella di origine nella versione clonata. |
numRemovedFiles |
Numero di file rimossi dalla tabella di destinazione se è stata sostituita una tabella precedente. |
removedFilesSize |
Dimensioni totali in byte dei file rimossi dalla tabella di destinazione se è stata sostituita una tabella precedente. |
numCopiedFiles |
Numero di file copiati nel nuovo percorso. 0 per cloni superficiali. |
copiedFilesSize |
Le dimensioni totali in byte dei file copiati nel nuovo percorso. 0 per cloni superficiali. |
RESTORE
Per questa operazione sono disponibili le metriche seguenti:
| Nome della metrica di misura | Description |
|---|---|
tableSizeAfterRestore |
Dimensioni della tabella in byte dopo il ripristino. |
numOfFilesAfterRestore |
Numero di file nella tabella dopo il ripristino. |
numRemovedFiles |
Numero di file rimossi dall'operazione di ripristino. |
numRestoredFiles |
Numero di file aggiunti in seguito al ripristino. |
removedFilesSize |
Dimensioni in byte dei file rimossi dal ripristino. |
restoredFilesSize |
Dimensioni in byte dei file aggiunti dal ripristino. |
VACUUM
Per questa operazione sono disponibili le metriche seguenti:
| Nome della metrica di misura | Description |
|---|---|
numDeletedFiles |
Numero di file eliminati. |
numVacuumedDirectories |
Il numero di directory sottoposte a vacuum. |
numFilesToDelete |
Numero di file da eliminare. |
Spostamento cronologico
Il viaggio nel tempo consente l'esecuzione di query sulle versioni precedenti della tabella in base al timestamp o alla versione della tabella, come registrato nel log delle transazioni. È possibile usare il tempo di viaggio per le applicazioni, ad esempio le seguenti:
- Ricreare analisi, report o output, ad esempio l'output di un modello di apprendimento automatico. Ciò può essere utile per il debug o il controllo, in particolare nei settori regolamentati.
- Scrivere query temporali complesse.
- Correggere gli errori nei dati.
- Fornire isolamento dello snapshot per un set di query per tabelle a modifica rapida.
Nota
In Databricks Runtime 18.0 e versioni successive le query di spostamento del tempo vengono bloccate se richiedono una versione precedente alla proprietà della deletedFileRetentionDuration tabella (impostazione predefinita 7 giorni). Per le tabelle gestite di Unity Catalog, questo vale per Databricks Runtime 12.2 e versioni successive.
Sintassi di spostamento temporale
Per eseguire una query su una tabella con time travel, aggiungere una clausola dopo la specifica del nome della tabella.
-
timestamp_expressionpuò essere uno qualsiasi di:-
'2018-10-18T22:15:12.013Z', ovvero una stringa che può essere convertita in un timestamp cast('2018-10-18 13:36:32 CEST' as timestamp)-
'2018-10-18', ovvero una stringa di data current_timestamp() - interval 12 hoursdate_sub(current_date(), 1)- Qualsiasi altra espressione che è o può essere convertita in un timestamp
-
-
versionè un valore long che può essere ottenuto dall'output diDESCRIBE HISTORY table_spec.
Né timestamp_expression né version possono essere sottoquery.
Vengono accettate solo stringhe di data o timestamp. Ad esempio, "2019-01-01" e "2019-01-01T00:00:00.000Z". Vedere il codice seguente per una sintassi di esempio:
SQL
SELECT * FROM people10m TIMESTAMP AS OF '2018-10-18T22:15:12.013Z';
SELECT * FROM people10m VERSION AS OF 123;
Python
df1 = spark.read.option("timestampAsOf", "2019-01-01").table("people10m")
df2 = spark.read.option("versionAsOf", 123).table("people10m")
È anche possibile usare la @ sintassi per specificare il timestamp o la versione come parte del nome della tabella. Il timestamp deve essere in yyyyMMddHHmmssSSS formato . È possibile specificare una versione con @v. Vedere il codice seguente per una sintassi di esempio:
SQL
-- Timestamp version
SELECT * FROM people10m@20190101000000000
-- Version number
SELECT * FROM people10m@v123
Python
# Timestamp version
spark.read.table("people10m@20190101000000000")
# Version number
spark.read.table("people10m@v123")
Configurare la conservazione dei dati per le query di spostamento del tempo
Per eseguire una query su una versione precedente della tabella, è necessario conservare sia il log che i file di dati per tale versione:
- I file di dati vengono eliminati quando
VACUUMviene eseguito su una tabella. - I file di log vengono rimossi automaticamente dopo il checkpoint delle versioni delle tabelle.
Per aumentare la soglia di conservazione dei dati per le tabelle, è necessario configurare le proprietà della tabella seguenti, sostituendo <format> con delta o iceberg:
-
<format>.logRetentionDuration = "interval <interval>": controlla per quanto tempo viene mantenuta la cronologia di una tabella. Il valore predefinito èinterval 30 days.- In Databricks Runtime 18.0 e versioni successive deve
logRetentionDurationessere maggiore o uguale adeletedFileRetentionDuration. Per le tabelle gestite di Unity Catalog, questo vale per Databricks Runtime 12.2 e versioni successive.
- In Databricks Runtime 18.0 e versioni successive deve
-
<format>.deletedFileRetentionDuration = "interval <interval>": determina l'utilizzo della sogliaVACUUMper rimuovere i file di dati a cui non si fa più riferimento nella versione della tabella corrente. Il valore predefinito èinterval 7 days.
Ad esempio, per accedere a 30 giorni di dati cronologici, impostare delta.deletedFileRetentionDuration = "interval 30 days", che corrisponde all'impostazione predefinita per delta.logRetentionDuration.
Importante
L'aumento della soglia di conservazione dei dati può causare l'aumento dei costi di archiviazione, man mano che vengono mantenuti più file di dati.
È possibile specificare le proprietà della tabella durante la creazione della tabella o impostarle con un'istruzione ALTER TABLE . Vedere Informazioni di riferimento sulle proprietà della tabella.
Esempi di viaggi in tempo
Per correggere le eliminazioni accidentali in una tabella per l'utente 111:
INSERT INTO my_table
SELECT * FROM my_table TIMESTAMP AS OF date_sub(current_date(), 1)
WHERE userId = 111
Per correggere gli aggiornamenti accidentali non corretti in una tabella:
MERGE INTO my_table target
USING my_table TIMESTAMP AS OF date_sub(current_date(), 1) source
ON source.userId = target.userId
WHEN MATCHED THEN UPDATE SET *
Per eseguire una query sul numero di nuovi clienti aggiunti nell'ultima settimana:
SELECT
(
SELECT count(distinct userId)
FROM my_table
)
-
(
SELECT count(distinct userId)
FROM my_table TIMESTAMP AS OF date_sub(current_date(), 7)
) AS new_customers
Checkpoint del log delle transazioni
Il log delle transazioni registra le versioni della tabella come file JSON all'interno della directory del log delle transazioni insieme ai dati della tabella.
Per ottimizzare l'esecuzione di query di checkpoint, le versioni delle tabelle vengono aggregate ai file di checkpoint Parquet, che migliorano le prestazioni impedendo la necessità di leggere tutte le versioni JSON della cronologia delle tabelle. Gli utenti non devono interagire direttamente con i checkpoint.
Azure Databricks ottimizza la frequenza di checkpoint per le dimensioni dei dati e il carico di lavoro. La frequenza del checkpoint è soggetta a modifiche senza preavviso.
Ripristinare uno stato precedente di una tabella
Usare il RESTORE comando per ripristinare una tabella in una versione o un timestamp precedente, incluso per questi scenari:
- È possibile ripristinare una tabella già ripristinata.
- È possibile ripristinare una tabella clonata .
Considerare i requisiti seguenti:
- Per ripristinare una tabella, è necessario disporre
MODIFYdell'autorizzazione per la tabella. - Dopo l'eliminazione dei file di dati, manualmente o da
VACUUM, non è possibile ripristinare una tabella in una versione precedente che fa riferimento a tali file. Il ripristino in questa versione parzialmente è comunque possibile sespark.sql.files.ignoreMissingFilesè impostato sutrue. - Per eseguire il ripristino in base al timestamp, usare i formati
yyyy-MM-dd HH:mm:ssoyyyy-MM-dd.
RESTORE TABLE target_table TO VERSION AS OF <version>;
RESTORE TABLE target_table TO TIMESTAMP AS OF <timestamp>;
Per informazioni dettagliate sulla sintassi, vedere RESTORE.
Comportamento di streaming
Il ripristino è un'operazione di modifica dei dati e potrebbe comportare dati duplicati per i carichi di lavoro downstream. Le voci di log aggiunte dal RESTORE comando contengono dataChange impostato su true.
Per i carichi di lavoro downstream, ad esempio un processo di streaming strutturato che elabora gli aggiornamenti a una tabella, le voci del log delle modifiche dei dati aggiunte dall'operazione di ripristino sono considerate nuovi aggiornamenti dei dati e l'elaborazione può comportare dati duplicati.
Per esempio:
| Versione della tabella | Operation | Aggiornamenti del log | Registrazioni negli aggiornamenti del registro di modifiche dei dati |
|---|---|---|---|
| 0 | INSERT |
AddFile(/path/to/file-1, dataChange = true) |
(name = Victor, age = 29), (name = George, age = 55) |
| 1 | INSERT |
AddFile(/path/to/file-2, dataChange = true) |
(nome = George, età = 39) |
| 2 | OPTIMIZE |
AddFile(/path/to/file-3, dataChange = false), RemoveFile(/path/to/file-1), RemoveFile(/path/to/file-2) |
Nessun record.
OPTIMIZE la compattazione non modifica i dati nella tabella. |
| 3 | RESTORE(version=1) |
RemoveFile(/path/to/file-3), AddFile(/path/to/file-1, dataChange = true), AddFile(/path/to/file-2, dataChange = true) |
(name = Victor, age = 29), (name = George, age = 55), (name = George, age = 39) |
Nell'esempio precedente, il RESTORE comando restituisce gli aggiornamenti visualizzati in precedenza durante la lettura della tabella 0 e 1. Se una query di streaming legge nuovamente questa tabella, questi file vengono considerati come dati appena aggiunti e vengono elaborati di nuovo.
Ripristinare le metriche
Al termine dell'operazione, RESTORE riporta le seguenti metriche in un DataFrame a riga singola:
table_size_after_restore: dimensioni della tabella dopo il ripristino.num_of_files_after_restore: numero di file nella tabella dopo il ripristino.num_removed_files: numero di file rimossi (eliminati logicamente) dalla tabella.num_restored_files: Numero di file ripristinati a seguito di rollback.removed_files_size: dimensione totale in byte dei file rimossi dalla tabella.restored_files_size: dimensioni totali in byte dei file ripristinati.
Trovare l'ultima versione del commit
Per ottenere il numero di versione dell'ultimo commit scritto dall'oggetto corrente SparkSession in tutti i thread e in tutte le tabelle, eseguire una query sulla configurazione SQL spark.databricks.<format>.lastCommitVersionInSession. Sostituire <format> con delta o iceberg, a seconda del formato della tabella.
Per esempio:
SQL
SET spark.databricks.delta.lastCommitVersionInSession
Python
spark.conf.get("spark.databricks.delta.lastCommitVersionInSession")
Scala
spark.conf.get("spark.databricks.delta.lastCommitVersionInSession")
Se non sono stati eseguiti commit da SparkSession, l'esecuzione della query sulla chiave restituisce un valore vuoto.
Nota
Se si condivide lo stesso SparkSession tra più thread, è simile alla condivisione di una variabile tra più thread. Potrebbero verificarsi condizioni di competizione durante gli aggiornamenti simultanei del valore di configurazione.