CREATE <objeto> … CLONE

Cria uma cópia de um objeto existente no sistema. Este comando é usado principalmente para criar clones zero-copy de bancos de dados, esquemas e tabelas. Você também pode usar este comando para criar clones de outros objetos de esquema, incluindo estágios externos, formatos de arquivo, sequências e funções de banco de dados.

O comando é uma variação dos comandos CREATE <objeto> específicos do objeto com a adição da palavra-chave CLONE.

Clonagem de objetos usando Time Travel

Para bancos de dados, esquemas e tabelas não temporárias, CLONE oferece suporte a uma cláusula adicional AT | BEFORE para clonagem usando Time Travel.

Para bancos de dados e esquemas:

Sintaxe

Bancos de dados, esquemas

CREATE [ OR REPLACE ] { DATABASE | SCHEMA } [ IF NOT EXISTS ] <object_name>
  CLONE <source_object_name>
    [ { AT | BEFORE } ( { TIMESTAMP => <timestamp> | OFFSET => <time_difference> | STATEMENT => <id> } ) ]
    [ IGNORE TABLES WITH INSUFFICIENT DATA RETENTION ]
    [ IGNORE HYBRID TABLES ]
  ...
Copy

Tabelas

CREATE [ OR REPLACE ] TABLE [ IF NOT EXISTS ] <object_name>
  CLONE <source_object_name>
    [ { AT | BEFORE } ( { TIMESTAMP => <timestamp> | OFFSET => <time_difference> | STATEMENT => <id> } ) ]
  ...
Copy

Tabelas dinâmicas

CREATE [ OR REPLACE ] DYNAMIC TABLE <name>
  CLONE <source_dynamic_table>
    [ { AT | BEFORE } ( { TIMESTAMP => <timestamp> | OFFSET => <time_difference> | STATEMENT => <id> } ) ]
  [
    TARGET_LAG = { '<num> { seconds | minutes | hours | days }' | DOWNSTREAM }
    WAREHOUSE = <warehouse_name>
  ]
Copy

Tabelas de eventos

CREATE [ OR REPLACE ] EVENT TABLE <name>
  CLONE <source_event_table>
    [ { AT | BEFORE } ( { TIMESTAMP => <timestamp> | OFFSET => <time_difference> | STATEMENT => <id> } ) ]
Copy

Tabelas Apache Iceberg™

CREATE [ OR REPLACE ] ICEBERG TABLE [ IF NOT EXISTS ] <name>
  CLONE <source_iceberg_table>
    [ { AT | BEFORE } ( { TIMESTAMP => <timestamp> | OFFSET => <time_difference> | STATEMENT => <id> } ) ]
    [ COPY GRANTS ]
    ...
Copy

Funções de banco de dados

CREATE [ OR REPLACE ] DATABASE ROLE [ IF NOT EXISTS ] <database_role_name>
  CLONE <source_database_role_name>
Copy

Outros objetos de esquema

CREATE [ OR REPLACE ] { ALERT | FILE FORMAT | SEQUENCE | STAGE | STREAM | TASK }
  [ IF NOT EXISTS ] <object_name>
  CLONE <source_object_name>
  ...
Copy

Parâmetros do Time Travel

{ AT | BEFORE } ( { TIMESTAMP => timestamp | OFFSET => time_difference | STATEMENT => id } )

A cláusula AT | BEFORE aceita um dos seguintes parâmetros:

TIMESTAMP => timestamp

Especifica uma data e hora exatas a serem usadas para o Time Travel. O valor deve ser explicitamente convertido para um tipo de dados TIMESTAMP, TIMESTAMP_LTZ, TIMESTAMP_NTZ ou TIMESTAMP_TZ.

Se nenhuma conversão explícita for especificada, o carimbo de data/hora na cláusula AT será tratado como um carimbo de data/hora com o fuso horário UTC (equivalente a TIMESTAMP_NTZ). Usar o tipo de dados TIMESTAMP para uma conversão explícita também pode fazer com que o valor seja tratado como um valor TIMESTAMP_NTZ. Para obter mais detalhes, consulte Tipos de dados de data e hora.

OFFSET => time_difference

Especifica a diferença em segundos do tempo atual a ser usado para o Time Travel, na forma -N onde N pode ser uma expressão inteira ou aritmética (por exemplo, -120 é 120 segundos, -30*60 é 1800 segundos ou 30 minutos).

STATEMENT => id

Especifica a ID de consulta de uma instrução a ser usada como ponto de referência para o Time Travel. Este parâmetro oferece suporte a qualquer instrução de um dos seguintes tipos:

  • DML (por exemplo, INSERT, UPDATE, DELETE)

  • TCL (transação BEGIN, COMMIT)

  • SELECT

A ID da consulta deve fazer referência a uma consulta que tenha sido executada nos últimos 14 dias. Se a ID da consulta fizer referência a uma consulta com mais de 14 dias, o seguinte erro é retornado:

Error: statement <query_id> not found

Para contornar esta limitação, use o carimbo de data/hora para a consulta referenciada.

IGNORE TABLES WITH INSUFFICIENT DATA RETENTION

Ignore tabelas que não possuem mais dados históricos disponíveis no Time Travel para clonar. Se a hora no passado especificada na cláusula AT | BEFORE ultrapassar o período de retenção de dados para qualquer tabela filho em um banco de dados ou esquema, ignore a operação de clonagem da tabela filho. Para obter mais informações, consulte Objetos filhos e tempo de retenção de dados.

IGNORE HYBRID TABLES

Ignore tabelas híbridas, que não serão clonadas. Use esta opção para clonar um banco de dados ou esquema que contém tabelas híbridas. O banco de dados ou esquema clonado inclui outros objetos, mas ignora tabelas híbridas.

Se você não usar esta opção e seu banco de dados ou esquema contiver uma ou mais tabelas híbridas, o comando ignorará as tabelas híbridas silenciosamente. No entanto, o tratamento de erro para bancos de dados e esquemas com tabelas híbridas mudará em um lançamento futuro; portanto, talvez você queira adicionar esse parâmetro aos seus comandos preventivamente.

Notas de uso geral

  • Um clone é gravável e independe de sua origem. As alterações feitas na origem ou no clone não são refletidas no outro objeto.

  • Os parâmetros que são explicitamente definidos em um banco de dados de origem, esquema ou tabela são mantidos em qualquer clone criado a partir do contêiner de origem ou de objetos filho.

  • Para criar um clone, sua função atual deve ter o(s) seguinte(s) privilégio(s) no objeto de origem:

    Funções de banco de dados:

    OWNERSHIP na função de banco de dados e o privilégio CREATE DATABASE ROLE no banco de dados de destino.

    Esquemas:

    Se você especificar a cláusula WITH MANAGED ACCESS, os privilégios necessários dependerão de o esquema de origem ser um esquema gerenciado ou não gerenciado. Para detalhes, consulte os privilégios CREATE SCHEMA.

    Tabelas:

    SELECT

    Alertas, canais, fluxos, tarefas:

    OWNERSHIP

    Outros objetos:

    USAGE

    Além disso, para clonar um esquema ou um objeto dentro de um esquema, sua função atual deve ter privilégios no(s) objeto(s) do contêiner, tanto para a origem quanto para o clone.

  • Para funções de banco de dados:

    • Uma função de banco de dados é clonada quando você executa o comando CREATE DATABASE … CLONE para clonar um banco de dados. No entanto, se você clonar outros objetos de banco de dados, como um esquema ou uma tabela, as funções de banco de dados no banco de dados não serão clonadas com o esquema ou a tabela.

    • Se a função de banco de dados já estiver clonada no banco de dados de destino, o comando falhará. Se isso ocorrer, descarte a função de banco de dados do banco de dados de destino e tente o comando CLONE novamente.

  • Para bancos de dados e esquemas, a clonagem é recursiva:

    • A clonagem de um banco de dados clona todos os esquemas e outros objetos do banco.

    • A clonagem de um esquema clona todos os objetos contidos no esquema.

    Entretanto, os seguintes tipos de objetos não são clonados:

    • Tabelas externas

    • Estágios internos (Snowflake)

  • Em bancos de dados, esquemas e tabelas, um clone não contribui para o armazenamento geral de dados do objeto até que sejam realizadas operações no clone que modifiquem dados existentes ou adicionem novos dados, como por exemplo:

    • Adicionar, excluir ou modificar linhas em uma tabela clonada.

    • Criação de uma nova tabela preenchida em um esquema clonado.

  • A clonagem de uma tabela replica a estrutura, os dados e outras propriedades (por exemplo, STAGE FILE FORMAT) da tabela de origem.

    No entanto:

    • Uma tabela clonada não inclui o histórico de carregamento da tabela de origem. Uma consequência disto é que os arquivos de dados que foram carregados em uma tabela de origem podem ser carregados novamente em seus clones.

    • Embora uma tabela clonada replique as chaves de clustering da tabela de origem, a nova tabela começa com Clustering automático suspenso – mesmo que o Clustering automático não esteja suspenso para a tabela de origem.

  • O parâmetro COPY GRANTS afeta um novo clone de tabela da seguinte forma:

    • Se o parâmetro COPY GRANTS for usado, o novo objeto herdará quaisquer privilégios de acesso explícitos concedidos na tabela original, mas não herdará nenhuma concessão futura definida para o tipo de objeto no esquema.

    • Se o parâmetro COPY GRANTS não for usado, o novo clone de objeto não herdará nenhum privilégio de acesso explícito concedido na tabela original, mas herdará quaisquer concessões futuras definidas para o tipo de objeto no esquema (usando a sintaxe GRANT <privilégios> … ON FUTURE).

    Nota

    Se a instrução estiver substituindo uma tabela existente com o mesmo nome, então as concessões são copiadas da tabela que está sendo substituída. Se não existir uma tabela com esse nome, então as concessões são copiadas da tabela de origem que está sendo clonada.

  • Para Tabelas Apache Iceberg™, a clonagem atualmente é compatível apenas para tabelas gerenciadas pelo Snowflake. Para obter mais informações, consulte Clonagem e tabelas Apache Iceberg™.

  • Em relação aos metadados:

    Atenção

    Os clientes devem garantir que nenhum dado pessoal (exceto para um objeto do usuário), dados sensíveis, dados controlados por exportação ou outros dados regulamentados sejam inseridos como metadados ao usar o serviço Snowflake. Para obter mais informações, consulte Campos de metadados no Snowflake.

  • Instruções CREATE OR REPLACE <object> são atômicas. Ou seja, quando um objeto é substituído, o objeto antigo é excluído e o novo objeto é criado em uma única transação.

Regras adicionais que se aplicam à clonagem de objetos

Metadados:

Um clone de objeto herda o nome e a estrutura do objeto de origem atual no momento em que a instrução CREATE <objeto> CLONE é executada ou em um momento/ponto especificado no passado usando Time Travel. Um clone de objeto herda quaisquer outros metadados, tais como comentários ou chaves de clustering de tabelas, que são atuais no objeto de origem no momento em que a instrução é executada, independentemente do uso do Time Travel.

Objetos filho:

Um banco de dados ou clone de esquema inclui todos os objetos filho ativos no momento em que a instrução é executada ou no momento/ponto especificado no passado. Um instantâneo dos dados da tabela representa o estado dos dados de origem quando a instrução é executada ou no momento/ponto especificado no passado. Os objetos filho herdam o nome e a estrutura dos objetos filho de origem no momento em que a instrução é executada.

Não clonado:

A clonagem de um banco de dados ou esquema não clona objetos dos seguintes tipos no banco de dados ou esquema:

  • Tabelas externas

  • Estágios internos (Snowflake)

Canais:

Um clone de esquema ou banco de dados inclui apenas objetos de canal que fazem referência a estágios externos (Amazon S3, Google Cloud Storage ou Microsoft Azure); canais internos (Snowflake) não são clonados.

O estado padrão de um clone de canal é o seguinte:

  • Quando AUTO_INGEST = FALSE, um canal clonado é pausado por padrão.

  • Quando AUTO_INGEST = TRUE, um canal clonado é definido como o estado STOPPED_CLONED. Nesse estado, os canais não acumulam notificações de evento como resultado de arquivos preparados recentemente. Quando um canal é explicitamente retomado, ele só processa arquivos de dados acionados como resultado de novas notificações de eventos.

Um clone de canal em qualquer estado pode ser retomado executando uma instrução ALTER PIPE … RESUME.

Tags:

A clonagem de um banco de dados ou esquema afeta as tags nesse banco de dados ou esquema, como segue:

  • Associações de tags no objeto de origem (por exemplo, tabela) são mantidas nos objetos clonados.

  • Para um banco de dados ou esquema:

    As tags armazenadas no banco de dados ou esquema também são clonadas.

    Quando um banco de dados ou esquema é clonado, as tags contidas no esquema ou banco de dados também são clonadas.

    Se existir uma tabela ou exibição no esquema de origem/banco de dados e houver referências a tags no mesmo esquema ou banco de dados, a tabela ou exibição clonada será mapeada para a tag clonada correspondente (no esquema/banco de dados de destino) em vez da tag no esquema ou banco de dados de origem.

UDF de Java:

Uma UDF de Java pode ser clonada quando o banco de dados ou esquema contendo a UDF de Java é clonado. Para ser clonada, a UDF de Java deve satisfazer determinadas condições. Para obter mais informações, consulte Limitações da clonagem.

Funções de métricas de dados:

A clonagem não resulta em atribuições de DMF no objeto de destino. Se você clonar um banco de dados ou esquema com DMFs, as DMFs serão clonadas para o banco de dados ou esquema de destino.

Dados da tabela:

Ao clonar um banco de dados, esquema ou tabela, um instantâneo dos dados em cada tabela é tirado e disponibilizado para o clone. O instantâneo representa o estado dos dados de origem no momento em que a instrução é executada ou no momento/ponto especificado no passado (usando Time Travel).

Referências de objetos:

Objetos como exibições, fluxos e tarefas incluem referências a objetos em sua definição. Por exemplo:

  • Uma exibição contém uma consulta armazenada que inclui referências de tabela.

  • Um fluxo aponta para uma tabela de origem.

  • Uma tarefa ou alerta chama um procedimento armazenado ou executa uma instrução SQL que faz referência a outros objetos.

Quando um desses objetos é clonado, seja em um banco de dados ou esquema clonado ou como um objeto individual, para aqueles tipos de objetos que oferecem suporte à clonagem, o clone herda referências a outros objetos a partir da definição do objeto de origem. Por exemplo, um clone de uma exibição herda a consulta armazenada da exibição de origem, incluindo as referências da tabela na consulta.

Preste muita atenção se algum nome de objeto na definição de um objeto de origem é total ou parcialmente qualificado. Um nome totalmente qualificado inclui o banco de dados e os nomes dos esquemas. Qualquer clone do objeto de origem inclui estas partes em sua própria definição.

Por exemplo:

-- Create a schema to serve as the source for a cloned schema.
CREATE SCHEMA source;

-- Create a table.
CREATE TABLE mytable (col1 string, col2 string);

-- Create a view that references the table with a fully-qualified name.
CREATE VIEW myview AS SELECT col1 FROM source.mytable;

-- Retrieve the DDL for the source schema.
SELECT GET_DDL ('schema', 'source', true);
Copy
+--------------------------------------------------------------------------+
| GET_DDL('SCHEMA', 'SOURCE', TRUE)                                        |
|--------------------------------------------------------------------------|
| create or replace schema MPETERS_DB.SOURCE;                              |
|                                                                          |
| create or replace TABLE MPETERS_DB.SOURCE.MYTABLE (                      |
|   COL1 VARCHAR(16777216),                                                |
|   COL2 VARCHAR(16777216)                                                 |
| );                                                                       |
|                                                                          |
| create view MPETERS_DB.SOURCE.MYVIEW as select col1 from SOURCE.MYTABLE; |
|                                                                          |
+--------------------------------------------------------------------------+
-- Clone the source schema.
CREATE SCHEMA source_clone CLONE source;

-- Retrieve the DDL for the clone of the source schema.
-- The clone of the view references the source table with the same fully-qualified name
-- as in the view in the source schema.
SELECT GET_DDL ('schema', 'source_clone', true);
Copy
+--------------------------------------------------------------------------------+
| GET_DDL('SCHEMA', 'SOURCE_CLONE', TRUE)                                        |
|--------------------------------------------------------------------------------|
| create or replace schema MPETERS_DB.SOURCE_CLONE;                              |
|                                                                                |
| create or replace TABLE MPETERS_DB.SOURCE_CLONE.MYTABLE (                      |
|   COL1 VARCHAR(16777216),                                                      |
|   COL2 VARCHAR(16777216)                                                       |
| );                                                                             |
|                                                                                |
| create view MPETERS_DB.SOURCE_CLONE.MYVIEW as select col1 from SOURCE.MYTABLE; |
|                                                                                |
+--------------------------------------------------------------------------------+

Se você pretende apontar uma exibição para tabelas com os mesmos nomes em outros bancos de dados ou esquemas, sugerimos criar uma nova exibição em vez de clonar uma exibição existente. Esta orientação também se refere a outros objetos que fazem referência a objetos em sua definição.

Nota

  • Certas limitações se aplicam às operações de clonagem. Por exemplo, instruções DDL que afetam o objeto de origem durante uma operação de clonagem podem alterar o resultado ou causar erros.

  • A clonagem não é instantânea, especialmente em grandes objetos (bancos de dados, esquemas, tabelas), e não bloqueia o objeto a ser clonado. Como tal, um clone não reflete nenhuma instrução DML aplicada aos dados da tabela, se aplicável, enquanto a operação de clonagem ainda estiver em andamento.

Para obter mais informações sobre este e outros casos de uso que possam afetar suas operações de clonagem, consulte Considerações sobre clonagem.

Notas para clonagem com Time Travel

  • A cláusula AT | BEFORE clona um banco de dados, esquema ou tabela a partir de uma hora especificada no passado ou com base em uma instrução SQL especificada:

    • A palavra-chave AT especifica que a solicitação inclui quaisquer alterações feitas por uma instrução ou transação com um carimbo de data/hora igual ao parâmetro especificado.

    • A palavra-chave BEFORE especifica que o pedido se refere a um ponto imediatamente anterior ao parâmetro especificado.

  • A clonagem usando STATEMENT é equivalente a usar TIMESTAMP com um valor igual ao tempo de execução registrado da instrução SQL (ou da transação que a envolve), conforme identificado pela ID da instrução especificada.

  • Um erro é devolvido se:

    • O objeto sendo clonado não existia no ponto no passado especificado na cláusula AT | BEFORE.

    • Os dados históricos necessários para clonar o objeto ou qualquer um de seus objetos filho (por exemplo, tabelas em esquemas ou banco de dados clonados) foram eliminados.

      Como solução alternativa para objetos filhos que foram eliminados do Time Travel, use o parâmetro IGNORE TABLES WITH INSUFFICIENT DATA RETENTION do comando CREATE <objeto> … CLONE. Para obter mais informações, consulte Objetos filhos e tempo de retenção de dados.

  • Se qualquer objeto filho em um banco de dados ou esquema clonado não existia no ponto no passado especificado na cláusula AT | BEFORE, o objeto filho não será clonado.

Para obter mais informações, consulte Compreensão e uso do Time Travel.

Solução de problemas de clonagem de objetos usando Time Travel

Os cenários a seguir podem ajudar você a solucionar problemas que podem ocorrer ao clonar um objeto usando o Time Travel.

Erro 

000707 (02000): Time travel data is not available for <object_type>
<object_name>. The requested time is either beyond the allowed time
travel period or before the object creation time.

Este erro pode ser retornado pelos seguintes motivos:

Causa

A hora no passado especificada pela cláusula AT | BEFORE ultrapassou o período de retenção de dados do objeto.

Solução

Verifique o período de retenção de dados do objeto usando o comando SHOW <objetos> apropriado e a coluna retention_time. Atualize a instrução CREATE <objeto> … CLONE para usar um horário no passado que esteja dentro do período de retenção de dados do objeto.

Causa

A operação de clonagem de um banco de dados ou esquema falhará se os dados históricos de qualquer objeto filho saírem do Time Travel.

Solução

Para ignorar tabelas secundárias que não possuem mais dados históricos disponíveis no Time Travel, execute a instrução de clonagem usando o parâmetro IGNORE TABLES WITH INSUFFICIENT DATA RETENTION para ignorar essas tabelas.

Causa

Em alguns casos, isto é causado pelo uso de uma cadeia de caracteres onde é esperado um carimbo de data/hora.

Solução

Converter a cadeia de caracteres em um carimbo de data/hora.

... AT(TIMESTAMP => '2023-12-31 12:00:00')               -- fails
... AT(TIMESTAMP => '2023-12-31 12:00:00'::TIMESTAMP)    -- succeeds
Copy

Exemplos

Clonar um banco de dados e todos os objetos dentro do banco de dados em seu estado atual:

CREATE DATABASE mytestdb_clone CLONE mytestdb;
Copy

Clonar um esquema e todos os objetos dentro do esquema em seu estado atual:

CREATE SCHEMA mytestschema_clone CLONE testschema;
Copy

Clonar uma tabela em seu estado atual:

CREATE TABLE orders_clone CLONE orders;
Copy

Clonar um esquema como ele existia antes da data e hora no carimbo de data/hora especificado:

CREATE SCHEMA mytestschema_clone_restore CLONE testschema
  BEFORE (TIMESTAMP => TO_TIMESTAMP(40*365*86400));
Copy

Clonar uma tabela como ela existia exatamente na data e na hora do carimbo de data/hora especificado:

CREATE TABLE orders_clone_restore CLONE orders
  AT (TIMESTAMP => TO_TIMESTAMP_TZ('04/05/2013 01:02:03', 'mm/dd/yyyy hh24:mi:ss'));
Copy

Clone uma tabela como ela existia imediatamente antes da execução da instrução especificada. Substitua o ID da consulta pelo parâmetro STATEMENT no exemplo e execute a instrução CREATE TABLE seguinte:

CREATE TABLE orders_clone_restore CLONE orders BEFORE (STATEMENT => '8e5d0ca9-005e-44e6-b858-a8f5b37c5726');
Copy

Clonar um banco de dados e todos os seus objetos como existiam há quatro dias e ignorar quaisquer tabelas que tenham um período de retenção de dados inferior a quatro dias:

CREATE DATABASE restored_db CLONE my_db
  AT (TIMESTAMP => DATEADD(days, -4, current_timestamp)::timestamp_tz)
  IGNORE TABLES WITH INSUFFICIENT DATA RETENTION;
Copy

Clone um esquema com tabelas padrão e tabelas híbridas:

CREATE OR REPLACE SCHEMA clone_ht_schema CLONE ht_schema
  IGNORE HYBRID TABLES;
Copy

O novo esquema conterá apenas as tabelas padrão do esquema original.