Práce s historií tabulek

U tabulek Apache Iceberg a Delta Lake každá operace, která upravuje tabulku, vytvoří novou verzi tabulky. Pomocí informací historie můžete auditovat operace, vrátit tabulku zpět nebo dotazovat tabulku v určitém časovém okamžiku pomocí časového cestování.

Note

Databricks nedoporučuje používat historii tabulek jako dlouhodobé řešení zálohování pro archivaci dat. Pokud jste nenastavili konfiguraci uchovávání dat i protokolů na větší hodnotu, použijte pouze posledních 7 dnů pro operace časového cestování.

Získat historii tabulky

Spuštěním DESCRIBE HISTORY příkazu načtěte informace, včetně operací, uživatele a časového razítka pro každý zápis do tabulky. Operace jsou řazeny v obráceném chronologickém pořadí.

Uchovávání historie tabulek je určeno nastavením logRetentionDurationtabulky, což je ve výchozím nastavení 30 dnů.

Note

Pohyb v čase a historie tabulky jsou řízeny různými prahovými hodnotami uchovávání dat. Viz Časová cesta.

DESCRIBE HISTORY table_name       -- get the full history of the table

DESCRIBE HISTORY table_name LIMIT 1  -- get the last operation only

Podrobnosti o syntaxi Spark SQL najdete v tématu DESCRIBE HISTORY.

Podrobnosti o syntaxi Scala, Java a Python najdete v dokumentaci k rozhraní Delta Lake API.

Průzkumník katalogu zobrazuje historii tabulek vizuálně na kartě Historie .

Schéma historie

Výstup operace history má následující sloupce.

Column Typ Description
verze long Verze tabulky vygenerovaná operací.
časové razítko timestamp Když byla tato verze potvrzena.
userId string ID uživatele, který operaci spustil.
uživatelské_jméno string Jméno uživatele, který operaci spustil.
operace string Název operace.
operační parametry map Parametry operace (například predikáty).)
úloha struct Podrobnosti úlohy Lakeflow, která operaci spustila. Vyplní se pouze u commitů zapsaných úlohou Lakeflow. V opačném případě null.
poznámkový blok struct Podrobnosti o poznámkovém bloku Databricks, ze kterého byla operace spuštěna. Vyplní se pouze pro commity vytvořené v poznámkovém bloku Databricks. V opačném případě null.
clusterId string ID clusteru, na kterém byla operace spuštěna.
readVersion long Verze tabulky, která byla přečtená k provedení operace zápisu.
isolationLevel string Úroveň izolace použitá pro tuto operaci.
isBlindAppend boolean Určuje, jestli tato operace připojila data.
operationMetrics map Metriky operace (například počet řádků a souborů upravených))
userMetadata string Metadata potvrzení definovaná uživatelem, pokud byla zadána.
+-------+-------------------+------+--------+---------+--------------------+----+--------+---------+-----------+-----------------+-------------+--------------------+
|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...|
+-------+-------------------+------+--------+---------+--------------------+----+--------+---------+-----------+-----------------+-------------+--------------------+

Note

Porozumění partitionBy provozním parametrům

Pole partitionBy v historii tabulek je smysluplné pouze pro operace CREATE a OVERWRITE, které definují nebo mění schéma oddílů tabulky.

Pro operace připojení k existujícím tabulkám (APPEND, INSERT, , UPDATEDELETE, MERGE) může toto pole zobrazovat prázdné pole [] nebo sloupce oddílů v závislosti na použité metodě zápisu (.save() vs .saveAsTable(). ).

Tato nekonzistence je očekávané chování a nemá vliv na způsob zápisu dat do oddílů. Neměli byste ho používat k ověření operací připojení.

Example

Zvažte tabulku dělenou podle date sloupce. Když vytvoříte tabulku, partitionBy se vyplní:

df.write.format("delta") \
  .partitionBy("date") \
  .saveAsTable("sales_data")

Operace CREATE v historii ukazuje:

operationParameters: {
  "mode": "ErrorIfExists",
  "partitionBy": "[\"date\"]"
}

Když k této tabulce připojíte data, partitionBy zobrazí se prázdné pole:

new_df.write.format("delta") \
  .mode("append") \
  .saveAsTable("sales_data")

Operace APPEND ukazuje:

operationParameters: {
  "mode": "Append",
  "partitionBy": "[]"
}

Očekává se prázdná partitionBy hodnota. Data jsou stále zapisována do správných oddílů na základě existujícího schématu oddílů tabulky. Všimněte si, že u .save() cesty se v tomto poli mohou zobrazovat sloupce oddílů, ale tento rozdíl je pouze detailem implementace a nemá vliv na chování při zápisu.

Metriky operací

Operace history vrátí kolekci metrik operací v mapě operationMetrics sloupců.

Následující tabulky uvádějí definice klíčů mapování podle operace.

WRITE, CREATE TABLE AS SELECT, REPLACE TABLE AS SELECT, COPY INTO

Pro tyto operace jsou k dispozici následující metriky:

Název metriky Description
numFiles Počet zapsaných souborů.
numOutputBytes Velikost v bajtech psaného obsahu.
numOutputRows Počet zapsaných řádků.

STREAMING UPDATE

Pro tuto operaci jsou k dispozici následující metriky:

Název metriky Description
numAddedFiles Počet přidaných souborů.
numRemovedFiles Počet odebraných souborů
numOutputRows Počet zapsaných řádků.
numOutputBytes Velikost zápisu v bajtech.

DELETE

Pro tuto operaci jsou k dispozici následující metriky:

Název metriky Description
numAddedFiles Počet přidaných souborů. Nezadá se při odstranění oddílů tabulky.
numRemovedFiles Počet odebraných souborů
numDeletedRows Počet odebraných řádků Nezadá se při odstranění oddílů tabulky.
numCopiedRows Počet řádků zkopírovaných v procesu odstraňování souborů.
executionTimeMs Doba potřebná ke spuštění celé operace.
scanTimeMs Doba potřebná ke kontrole shodných souborů.
rewriteTimeMs Doba potřebná k přepsání odpovídajících souborů.

TRUNCATE

Pro tuto operaci jsou k dispozici následující metriky:

Název metriky Description
numRemovedFiles Počet odebraných souborů
executionTimeMs Doba potřebná ke spuštění celé operace.

MERGE

Pro tuto operaci jsou k dispozici následující metriky:

Název metriky Description
numSourceRows Počet řádků ve zdrojovém datovém rámci
numTargetRowsInserted Počet řádků vložených do cílové tabulky
numTargetRowsUpdated Počet řádků aktualizovaných v cílové tabulce
numTargetRowsDeleted Počet řádků odstraněných v cílové tabulce
numTargetRowsCopied Počet zkopírovaných cílových řádků
numOutputRows Celkový počet odpsaných řádků.
numTargetFilesAdded Počet souborů přidaných do jímky (cíl).
numTargetFilesRemoved Počet souborů odebraných z jímky (cíl).
executionTimeMs Doba potřebná ke spuštění celé operace.
scanTimeMs Doba potřebná ke kontrole shodných souborů.
rewriteTimeMs Doba potřebná k přepsání odpovídajících souborů.

UPDATE

Pro tuto operaci jsou k dispozici následující metriky:

Název metriky Description
numAddedFiles Počet přidaných souborů.
numRemovedFiles Počet odebraných souborů
numUpdatedRows Počet aktualizovaných řádků.
numCopiedRows Počet řádků, které byly právě zkopírovány během aktualizace souborů.
executionTimeMs Doba potřebná ke spuštění celé operace.
scanTimeMs Doba potřebná ke kontrole shodných souborů.
rewriteTimeMs Doba potřebná k přepsání odpovídajících souborů.

FSCK

Pro tuto operaci jsou k dispozici následující metriky:

Název metriky Description
numRemovedFiles Počet odebraných souborů

CONVERT

Pro tuto operaci jsou k dispozici následující metriky:

Název metriky Description
numConvertedFiles Počet převedených souborů Parquet.

OPTIMIZE

Pro tuto operaci jsou k dispozici následující metriky:

Název metriky Description
numAddedFiles Počet přidaných souborů.
numRemovedFiles Počet optimalizovaných souborů.
numAddedBytes Počet bajtů přidaných po optimalizaci tabulky
numRemovedBytes Počet odebraných bajtů
minFileSize Velikost nejmenšího souboru po optimalizaci tabulky
p25FileSize Velikost 25. percentilového souboru po optimalizaci tabulky.
p50FileSize Velikost mediánu souboru po optimalizaci tabulky
p75FileSize Velikost souboru 75. percentilu po optimalizaci tabulky.
maxFileSize Velikost největšího souboru po optimalizaci tabulky

CLONE

Pro tuto operaci jsou k dispozici následující metriky:

Název metriky Description
sourceTableSize Velikost v bajtech zdrojové tabulky ve verzi, která je naklonovaná.
sourceNumOfFiles Počet souborů ve zdrojové tabulce v naklonované verzi.
numRemovedFiles Počet souborů odebraných z cílové tabulky, pokud byla nahrazena předchozí tabulka.
removedFilesSize Celková velikost v bajtech souborů odebraných z cílové tabulky, pokud byla nahrazena předchozí tabulka.
numCopiedFiles Počet souborů, které byly zkopírovány do nového umístění. 0 pro mělké klony.
copiedFilesSize Celková velikost v bajtech souborů, které byly zkopírovány do nového umístění. 0 pro mělké klony.

RESTORE

Pro tuto operaci jsou k dispozici následující metriky:

Název metriky Description
tableSizeAfterRestore Velikost tabulky v bajtech po obnovení.
numOfFilesAfterRestore Počet souborů v tabulce po obnovení
numRemovedFiles Počet souborů odebraných operací obnovení
numRestoredFiles Počet souborů, které byly přidány v důsledku obnovení.
removedFilesSize Velikost v bajtech souborů odebraných obnovením
restoredFilesSize Velikost v bajtech souborů přidaných obnovením.

VACUUM

Pro tuto operaci jsou k dispozici následující metriky:

Název metriky Description
numDeletedFiles Počet odstraněných souborů.
numVacuumedDirectories Počet vakuovaných adresářů.
numFilesToDelete Počet souborů, které chcete odstranit.

Časová cesta

Funkce časového skoku podporuje vyhledávání předchozích verzí tabulek na základě časového razítka nebo verze tabulky, jak je zaznamenáno v transakčním záznamu. Můžete použít cestování časem pro aplikace, jako jsou například tyto:

  • Opětovné vytváření analýz, sestav nebo výstupů, jako je výstup modelu strojového učení. To může být užitečné pro ladění nebo auditování, zejména v regulovaných odvětvích.
  • Psaní složitých dočasných dotazů
  • Oprava chyb v datech
  • Poskytuje izolaci snímků pro sadu dotazů pro rychlé změny tabulek.

Note

V Databricks Runtime 18.0 a novějších jsou dotazy na historická data blokovány, pokud požadují verzi starší, než je vlastnost tabulky „deletedFileRetentionDuration“ (výchozí 7 dnů). Pro spravované tabulky v Katalogu Unity platí od verze Databricks Runtime 12.2 a vyšší.

Syntaxe časového cestování

Dotazujete se na tabulku s časovým cestováním přidáním klauzule za specifikaci názvu tabulky.

  • timestamp_expression může být libovolná z těchto možností:
    • '2018-10-18T22:15:12.013Z', to znamená řetězec, který lze převést na časové razítko.
    • cast('2018-10-18 13:36:32 CEST' as timestamp)
    • '2018-10-18', to je řetězec data.
    • current_timestamp() - interval 12 hours
    • date_sub(current_date(), 1)
    • Jakýkoli jiný výraz, který je nebo lze převést na časové razítko
  • version je dlouhá hodnota, kterou lze získat z výstupu DESCRIBE HISTORY table_spec.

timestamp_expression Ani version nemůže být poddotaz.

Akceptují se pouze řetězce data nebo časového razítka. Příklad: "2019-01-01" a "2019-01-01T00:00:00.000Z". Příklad syntaxe najdete v následujícím kódu:

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")

Syntaxi můžete také použít @ k určení časového razítka nebo verze jako součásti názvu tabulky. Časové razítko musí být ve yyyyMMddHHmmssSSS formátu. Můžete zadat verzi pomocí @v. Příklad syntaxe najdete v následujícím kódu:

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")

Konfigurace uchovávání dat pro dotazy na časové cesty

Pokud chcete dotazovat předchozí verzi tabulky, musíte zachovat protokol i datové soubory pro danou verzi:

  • Datové soubory se odstraní, když VACUUM běží proti tabulce.
  • Soubory protokolu se odeberou automaticky po verzích tabulek kontrolních bodů.

Chcete-li zvýšit práh uchovávání dat pro tabulky, musíte nakonfigurovat následující vlastnosti tabulky a nahradit <format> buď delta, nebo iceberg:

  • <format>.logRetentionDuration = "interval <interval>": Určuje, jak dlouho se historie tabulky uchovává. Výchozí hodnota je interval 30 days.
    • V Databricks Runtime 18.0 a vyšší musí logRetentionDuration být větší nebo rovno deletedFileRetentionDuration. Pro spravované tabulky v Katalogu Unity platí od verze Databricks Runtime 12.2 a vyšší.
  • <format>.deletedFileRetentionDuration = "interval <interval>": určuje prahovou hodnotu VACUUM , která se používá k odebrání datových souborů, na které se už v aktuální verzi tabulky neodkazuje. Výchozí hodnota je interval 7 days.

Pokud například chcete získat přístup k historickým datům o 30 dnech, nastavte delta.deletedFileRetentionDuration = "interval 30 days", který odpovídá výchozímu nastavení pro delta.logRetentionDuration.

Important

Zvýšení prahové hodnoty uchovávání dat může způsobit zvýšení nákladů na úložiště, protože se udržuje více datových souborů.

Během vytváření tabulky můžete zadat vlastnosti tabulky nebo je nastavit pomocí ALTER TABLE příkazu. Viz referenční informace k vlastnostem tabulky.

Příklady časových cest

Opravit náhodné smazání u tabulky pro uživatele 111:

INSERT INTO my_table
  SELECT * FROM my_table TIMESTAMP AS OF date_sub(current_date(), 1)
  WHERE userId = 111

Oprava náhodných nesprávných aktualizací tabulky:

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 *

Dotazování počtu nových zákazníků přidaných za poslední týden:

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

Kontrolní body transakčního protokolu

Transakční protokol zaznamenává verze tabulek jako soubory JSON v adresáři transakčního protokolu spolu s daty tabulky.

Kvůli optimalizaci dotazování kontrolních bodů se verze tabulek agregují do souborů kontrolních bodů Parquet, což zvyšuje výkon tím, že brání nutnosti číst všechny verze tabulek JSON historie. Uživatelé nemusí přímo pracovat s kontrolními body.

Azure Databricks optimalizuje frekvenci vytváření kontrolních bodů pro velikost dat a úlohu. Četnost kontrolních bodů se může bez předchozího upozornění změnit.

Obnovení tabulky do dřívějšího stavu

RESTORE Pomocí příkazu obnovte tabulku do předchozí verze nebo časového razítka, včetně těchto scénářů:

Vezměte v úvahu následující požadavky:

  • Pokud chcete obnovit tabulku, musíte mít MODIFY oprávnění k tabulce.
  • Po odstranění datových souborů ručně nebo podle VACUUMnemůžete obnovit tabulku do starší verze, která odkazuje na tyto soubory. Obnovení do této verze je stále možné, pokud spark.sql.files.ignoreMissingFiles je nastavena na true.
  • K obnovení podle časového razítka použijte formáty yyyy-MM-dd HH:mm:ss nebo yyyy-MM-dd.
RESTORE TABLE target_table TO VERSION AS OF <version>;
RESTORE TABLE target_table TO TIMESTAMP AS OF <timestamp>;

Podrobnosti o syntaxi najdete v sekci RESTORE.

Chování při streamování

Obnovení je operace změny dat a může vést k duplicitním datům pro podřízené úlohy. Položky protokolu přidané příkazem RESTORE obsahují dataChange nastavenou na true.

U podřízených úloh, jako je úloha strukturovaného streamování , která zpracovává aktualizace tabulky, se položky protokolu změn dat přidané operací obnovení považují za nové aktualizace dat a jejich zpracování může vést k duplicitním datům.

Příklad:

Verze tabulky Operation Aktualizace protokolů Záznamy v aktualizacích protokolu změn dat
0 INSERT AddFile(/path/to/file-1, dataChange = true) (jméno = Viktor, věk = 29), (jméno = George, věk = 55)
1 INSERT AddFile(/path/to/file-2, dataChange = true) (name = George, age = 39)
2 OPTIMIZE AddFile(/path/to/file-3, dataChange = false), RemoveFile(/path/to/file-1), RemoveFile(/path/to/file-2) Žádné záznamy. OPTIMIZE komprimace nemění data v tabulce.
3 RESTORE(version=1) RemoveFile(/path/to/file-3), AddFile(/path/to/file-1, dataChange = true), AddFile(/path/to/file-2, dataChange = true) (jméno = Viktor, věk = 29), (jméno = George, věk = 55), (jméno = George, věk = 39)

V předchozím příkladu RESTORE má příkaz za následek aktualizace, které byly dříve zobrazeny při čtení tabulky verze 0 a 1. Pokud streamovací dotaz přečte tuto tabulku znovu, považují se tyto soubory za nově přidaná data a zpracovávají se znovu.

Obnovení metrik

Po dokončení RESTORE uvede následující metriky jako datový rámec o jednom řádku:

  • table_size_after_restore: Velikost tabulky po obnovení.

  • num_of_files_after_restore: Počet souborů v tabulce po obnovení.

  • num_removed_files: Počet odebraných souborů (logicky odstraněných) z tabulky.

  • num_restored_files: Počet obnovených souborů kvůli vrácení zpět

  • removed_files_size: Celková velikost v bajtech souborů, které jsou z tabulky odebrány.

  • restored_files_size: Celková velikost v bajtech obnovených souborů.

    Příklad obnovení metrik

Najít poslední verzi commitu

Pokud chcete získat číslo verze posledního potvrzení napsaného aktuální SparkSession ve všech vláknech a všech tabulkách, proveďte dotaz na SQL konfiguraci spark.databricks.<format>.lastCommitVersionInSession. Nahraďte <format> buď delta, nebo iceberg podle formátu tabulky.

Příklad:

SQL

SET spark.databricks.delta.lastCommitVersionInSession

Python

spark.conf.get("spark.databricks.delta.lastCommitVersionInSession")

Scala

spark.conf.get("spark.databricks.delta.lastCommitVersionInSession")

Pokud nebyly provedeny žádné SparkSessioncommity, dotazování na klíč vrátí prázdnou hodnotu.

Note

Pokud sdílíte totéž SparkSession ve více vláknech, je to podobné sdílení proměnné napříč několika vlákny. U souběžných aktualizací konfigurační hodnoty můžete narazit na podmínky časování.