Clonar uma tabela no Azure Databricks

Você pode criar uma cópia de uma tabela Delta Lake existente no Azure Databricks em uma versão específica usando o clone comando. Os clones podem ser profundos ou superficiais.

O Azure Databricks também suporta a clonagem de tabelas Parquet e Iceberg. Veja Tabelas de Parquet e Iceberg clonadas incrementalmente para Delta Lake.

Para obter detalhes sobre como usar o clone com o Unity Catalog, consulte Clone superficial para tabelas do Unity Catalog.

Nota

O Databricks recomenda o uso do Delta Sharing para fornecer acesso somente leitura a tabelas em diferentes organizações. Consulte Compartilhar dados e ativos de IA com segurança usando o Delta Sharing.

Tipos de clones

  • Um clone profundo é um clone que copia os dados da tabela de origem para o destino do clone, além dos metadados da tabela existente. Além disso, os metadados de fluxo também são clonados de tal forma que um fluxo que grava na tabela Delta pode ser interrompido em uma tabela de origem e continuado no destino de um clone de onde parou.
  • Um clone superficial é um clone que não copia os arquivos de dados para o destino do clone. Os metadados da tabela são equivalentes à fonte. Estes clones são mais baratos de criar.

Os metadados clonados incluem: esquema, informações de particionamento, invariantes, anulabilidade. Apenas para clones profundos, os metadados stream e COPY INTO também são clonados. Os metadados não clonados são a descrição da tabela e os metadados de confirmação definidos pelo usuário.

Qual é a semântica das operações de clone Delta?

Se você tiver trabalhado com uma tabela Delta registrada no metastore do Hive ou com uma coleção de arquivos não registrados como uma tabela, o clone terá a seguinte semântica:

Importante

No Databricks Runtime 13.3 LTS e superior, as tabelas gerenciadas do Unity Catalog têm suporte para clones superficiais. A semântica de clones para tabelas do Unity Catalog difere significativamente da semântica de clones do Delta Lake em outros ambientes. Consulte Clone superficial para tabelas do Catálogo Unity.

  • Quaisquer alterações feitas em clones profundos ou superficiais afetam apenas os próprios clones e não a tabela de origem.
  • Clones superficiais fazem referência a arquivos de dados no diretório de origem. Se você executar vacuum na tabela de origem, os clientes não poderão mais ler os arquivos de dados referenciados e um FileNotFoundException será lançado. Nesse caso, a execução do clone com substituição sobre o clone superficial repara o clone. Se isso ocorrer com frequência, considere usar um clone profundo em vez disso, que não depende da tabela de origem.
  • Os clones profundos não dependem da fonte a partir da qual foram clonados, mas são caros de criar porque um clone profundo copia os dados, bem como os metadados.
  • A clonagem com replace um destino que já tenha uma tabela nesse caminho cria um log Delta se não existir um nesse caminho. Você pode limpar todos os dados existentes executando vacuum.
  • Para tabelas Delta existentes, uma nova confirmação é criada que inclui os novos metadados e novos dados da tabela de origem. Essa nova confirmação é incremental, o que significa que apenas novas alterações desde o último clone são confirmadas na tabela.
  • Clonar uma tabela não é o mesmo que Create Table As Select ou CTAS. Um clone copia os metadados da tabela de origem, além dos dados. A clonagem também tem uma sintaxe mais simples: você não precisa especificar particionamento, formato, invariantes, anulabilidade e assim por diante, pois eles são retirados da tabela de origem.
  • Uma tabela clonada tem um histórico independente de sua tabela de origem. As consultas de viagem no tempo em uma tabela clonada não funcionam com as mesmas entradas que funcionam em sua tabela de origem.

Exemplo de sintaxe de clone

Os exemplos de código a seguir demonstram sintaxe para criar clones profundos e superficiais:

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

Para obter detalhes de sintaxe, consulte CREATE TABLE CLONE.

Métricas de clonagem

CLONE relata as seguintes métricas como um DataFrame de linha única quando a operação for concluída:

  • source_table_size: Tamanho da tabela de origem que está sendo clonada em bytes.
  • source_num_of_files: O número de arquivos na tabela de origem.
  • num_removed_files: Se a tabela estiver sendo substituída, quantos arquivos serão removidos da tabela atual.
  • num_copied_files: Número de arquivos que foram copiados da origem (0 para clones superficiais).
  • removed_files_size: Tamanho em bytes dos arquivos que estão sendo removidos da tabela atual.
  • copied_files_size: Tamanho em bytes dos arquivos copiados para a tabela.

Exemplo de métricas de clonagem

Permissões

Você deve configurar permissões para o controle de acesso à tabela do Azure Databricks e seu provedor de nuvem.

Controlo de acesso a tabelas

As seguintes permissões são necessárias para clones profundos e superficiais:

  • SELECT permissão na tabela de origem.
  • Se você estiver usando CLONE para criar uma nova tabela, CREATE permissão no banco de dados no qual você está criando a tabela.
  • Se você estiver usando CLONE para substituir uma tabela, você deve ter MODIFY permissão na tabela.

Permissões do provedor de nuvem

Se você criou um clone profundo, qualquer usuário que leia o clone profundo deve ter acesso de leitura ao diretório do clone. Para fazer alterações no clone, os usuários devem ter acesso de gravação ao diretório do clone.

Se você criou um clone superficial, qualquer usuário que leia o clone superficial precisa de permissão para ler os arquivos na tabela original, uma vez que os arquivos de dados permanecem na tabela de origem com clones superficiais, bem como o diretório do clone. Para fazer alterações no clone, os usuários precisarão de acesso de gravação ao diretório do clone.

Usar clone para arquivamento de dados

Você pode usar o clone profundo para preservar o estado de uma tabela em um determinado momento para fins de arquivamento. Você pode sincronizar clones profundos incrementalmente para manter um estado atualizado de uma tabela de origem para recuperação de desastres.

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

Usar clone para reprodução de modelo de ML

Ao fazer o aprendizado de máquina, você pode querer arquivar uma determinada versão de uma tabela na qual você treinou um modelo de ML. Modelos futuros podem ser testados usando este conjunto de dados arquivados.

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

Use clone para experimentos de curto prazo em uma mesa de produção

Para testar um fluxo de trabalho em uma tabela de produção sem corromper a tabela, você pode criar facilmente um clone superficial. Isso permite executar fluxos de trabalho arbitrários na tabela clonada que contém todos os dados de produção, mas não afeta nenhuma carga de trabalho de produção.

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

Usar clone para substituir propriedades da tabela

Nota

Disponível no Databricks Runtime 7.5 e superior.

As substituições de propriedades de tabela são particularmente úteis para:

  • Anotação de tabelas com informações do proprietário ou usuário ao compartilhar dados com diferentes unidades de negócios.
  • É necessário arquivar tabelas Delta e histórico de tabelas ou viagens no tempo. Você pode especificar os dados e os períodos de retenção de log independentemente para a tabela de arquivamento. Por exemplo:

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)