Cloner une table sur Azure Databricks

Vous pouvez créer une copie d’une table Delta Lake existante sur Azure Databricks correspondant à une version spécifique à l’aide de la commande clone. Les clones peuvent être profonds ou superficiels.

Azure Databricks prend également en charge le clonage de tables Parquet et Iceberg. Consultez cloner de manière incrémentielle les tableaux Parquet et Iceberg vers Delta Lake.

Pour plus d’informations sur l’utilisation de clones avec Unity Catalog, consultez Clone superficiel pour les tables Unity Catalog.

Remarque

Databricks recommande d’utiliser le partage Delta pour fournir un accès en lecture seule aux tables dans différentes organisations. Consultez Partager des données et des ressources IA de façon sécurisée à l’aide du partage Delta.

Cloner des types

  • Un clone profond copie les données de la table source vers la cible de clone en plus des métadonnées de la table existante. En outre, des métadonnées de flux sont également clonées, de sorte qu’un flux qui écrit dans la table Delta peut être arrêté sur une table source, et poursuivi sur la cible d’un clone à partir de là où il s’est arrêté.
  • Un clone superficiel ne copie pas les fichiers de données vers la cible de clone. Les métadonnées de la table sont équivalentes à la source. La création de ces clones est moins coûteuse.

Les métadonnées clonées incluent les éléments suivants : schéma, informations de partitionnement, invariants, possibilité de valeur NULL. Pour les clones profonds uniquement, le flux et les métadonnées de la commande COPY INTO sont également clonés. Les métadonnées non clonées sont la description de la table et les métadonnées de validation définies par l’utilisateur.

Quelle est la sémantique des opérations de clonage Delta ?

Si vous avez travaillé avec une table Delta inscrite dans le metastore Hive ou une collection de fichiers non inscrits en tant que table, le clone a la sémantique suivante :

Important

Dans Databricks Runtime 13.1 et versions ultérieures, les tables managées Unity Catalog prennent en charge les clones superficiels. La sémantique de clonage des tables Unity Catalog diffère considérablement de la sémantique de clonage Delta Lake dans d’autres environnements. Consultez Clone superficiel pour les tables Unity Catalog.

  • Toute modification apportée à des clones profonds ou superficiels n’affecte que ceux-ci, pas la table source.
  • Les clones superficiels référencent les fichiers de données dans le répertoire source. Si vous exécutez vacuum sur la table source, les clients ne peuvent plus lire les fichiers de données référencés et une exception FileNotFoundException est levée. Dans ce cas, l’exécution d’un clone avec remplacement sur le clone superficiel répare celui-ci. Si cela se produit souvent, envisagez plutôt d’utiliser un clone profond qui ne dépend pas de la table source.
  • Les clones profonds ne dépendent pas de la source à partir de laquelle ils ont été clonés, mais leur création est coûteuse, car un clone profond copie tant les données que les métadonnées.
  • Un clonage avec replace vers une cible qui a déjà une table dans ce chemin d’accès crée un journal Delta s’il n’en existe pas dans ce chemin d’accès. Vous pouvez nettoyer toutes les données existantes en exécutant vacuum.
  • Pour les tables Delta existantes, une nouvelle validation est créée, qui inclut les nouvelles métadonnées et données de la table source. Cette nouvelle validation étant incrémentielle, seules les nouvelles modifications apportées depuis le dernier clonage sont validées dans la table.
  • Le clonage d’une table n’est pas le même que Create Table As Select ou CTAS. Un clone copie les métadonnées de la table source en plus des données. Le clonage a également une syntaxe plus simple : vous n’avez pas besoin de spécifier le partitionnement, le format, les invariants, la possibilité de valeur NULL, etc. car ces informations sont extraites de la table source.
  • Une table clonée possède un historique indépendant de sa table source. Les requêtes de voyage dans le temps sur une table clonée ne fonctionnent pas avec les mêmes entrées que celles de sa table source.

Exemple de syntaxe de clonage

Les exemples de code suivants illustrent la syntaxe permettant de créer des clones profonds et superficiels :

SQL

CREATE TABLE delta.`/data/target/` CLONE delta.`/data/source/` -- Create a deep clone of /data/source at /data/target

CREATE OR REPLACE TABLE db.target_table CLONE db.source_table -- Replace the target

CREATE TABLE IF NOT EXISTS delta.`/data/target/` CLONE db.source_table -- No-op if the target table exists

CREATE TABLE db.target_table SHALLOW CLONE delta.`/data/source`

CREATE TABLE db.target_table SHALLOW CLONE delta.`/data/source` VERSION AS OF version

CREATE TABLE db.target_table SHALLOW CLONE delta.`/data/source` 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.forPath(spark, "/path/to/table")  # path-based tables, or
deltaTable = DeltaTable.forName(spark, "source_table")    # Hive metastore-based tables

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.forPath(spark, "/path/to/table")
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

Pour plus d’informations sur la syntaxe, consultez CREATE TABLE CLONE.

Cloner des métriques

CLONE présente les métriques suivantes sous la forme d’une ligne unique de tramedonnées une fois l’opération terminée :

  • source_table_size : taille en octets de la table source en cours de clonage.
  • source_num_of_files : nombre de fichiers dans la table source.
  • num_removed_files : si la table est en cours de remplacement, nombre de fichiers supprimés de la table actuelle.
  • num_copied_files : nombre de fichiers copiés à partir de la source (0 pour des clones superficiels).
  • removed_files_size : taille en octets des fichiers en cours de suppression de la table active.
  • copied_files_size : taille en octets des fichiers copiés vers la table.

Clone metrics example

Autorisations

Vous devez configurer des autorisations pour le contrôle d’accès aux table d’Azure Databricks et votre fournisseur de cloud.

Contrôle d’accès aux tables

Les autorisations suivantes sont requises pour les clones tant profonds que superficiels :

  • Autorisation SELECT sur la table source.
  • Si vous utilisez CLONE pour créer une table, autorisation CREATE sur la base de données dans laquelle vous la créez.
  • Si vous utilisez CLONE pour remplacer une table, vous devez disposer de l’autorisation MODIFY sur celle-ci.

Autorisations du fournisseur de cloud

Si vous avez créé un clone profond, tout utilisateur lisant celui-ci doit disposer d’un accès en lecture au répertoire du clone. Pour apporter des modifications au clone, les utilisateurs doivent disposer d’un accès en écriture au répertoire de celui-ci.

Si vous avez créé un clone superficiel, tout utilisateur lisant celui-ci a besoin d’une autorisation pour lire les fichiers dans la table d’origine, car les fichiers de données restent dans la table source avec le clone superficiel, ainsi que son répertoire. Pour apporter des modifications au clone, les utilisateurs ont besoin d’un accès en écriture au répertoire de celui-ci.

Utiliser le clonage pour l’archivage des données

Vous pouvez utiliser un clone profond pour conserver l’état d’une table à un point dans le temps donné à des fins d’archivage. Vous pouvez synchroniser les clones profonds de manière incrémentielle pour maintenir l’état mis à jour d’une table source pour la récupération d’urgence.

-- Every month run
CREATE OR REPLACE TABLE delta.`/some/archive/path` CLONE my_prod_table

Utiliser le clonage pour la reproduction de modèle ML

Dans le cadre d’un apprentissage automatique, vous pouvez archiver une certaine version d’une table sur laquelle vous avez effectué l'apprentissage d’un modèle ML. Des modèles futurs pourront être testés à l’aide de ce jeu de données archivé.

-- Trained model on version 15 of Delta table
CREATE TABLE delta.`/model/dataset` CLONE entire_dataset VERSION AS OF 15

Utiliser le clonage pour les expériences à court terme sur une table de production

Pour tester un flux de travail sur une table de production sans altérer celle-ci, vous pouvez facilement créer un clone superficiel. Cela vous permet d’exécuter des flux de travail arbitraires sur la table clonée contenant toutes les données de production, sans affecter les charges de travail de production.

-- 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;

Utiliser le clone pour remplacer les propriétés de table

Notes

Disponible dans Databricks Runtime 7.5 et versions ultérieures.

Les substitutions de propriété de table sont particulièrement utiles pour :

  • Annoter des tables avec des informations sur les propriétaires ou les utilisateurs lors du partage de données avec différentes unités commerciales.
  • L’archivage des tables Delta et de l’historique ou du voyage dans le temps des tables est requis. Vous pouvez spécifier les périodes de rétention du journal et des données de manière indépendante pour la table archive. Par exemple :

SQL

CREATE OR REPLACE TABLE archive.my_table CLONE prod.my_table
TBLPROPERTIES (
delta.logRetentionDuration = '3650 days',
delta.deletedFileRetentionDuration = '3650 days'
)
LOCATION 'xx://archive/my_table'

Python

dt = DeltaTable.forName(spark, "prod.my_table")
tblProps = {
"delta.logRetentionDuration": "3650 days",
"delta.deletedFileRetentionDuration": "3650 days"
}
dt.clone('xx://archive/my_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("xx://archive/my_table", isShallow = false, replace = true, properties = tblProps)