CREATE <objeto> … CLONE

Cria uma cópia de um objeto existente no sistema. Este comando é usado principalmente para criar clones de zero cópia de bancos de dados, esquemas e tabelas; no entanto, ele também pode ser usado para criar rapidamente/facilmente clones de outros objetos de esquema, como 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, CLONE oferece suporte ao parâmetro IGNORE TABLES WITH INSUFFICIENT DATA RETENTION para ignorar quaisquer tabelas que tenham sido eliminadas do Time Travel (por exemplo, tabelas transitórias com um período de retenção de dados de um dia).

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 ]
  ...
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

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 convertido explicitamente em um TIMESTAMP.

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.

Notas de uso geral

  • Um clone pode ser gravado e é independente de sua origem (ou seja, as mudanças 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.

    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 não é clonada quando você executa o comando CREATE CLONE para clonar um banco de dados ou outros objetos contidos no banco de dados. Você deve usar o comando CREATE DATABASE ROLE … CLONE para clonar uma função de banco de dados no banco de dados de destino.

    • 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, dados e algumas 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 CREATE TABLE … CLONE inclui as palavras-chave COPY GRANTS, que afetam um novo clone de tabela como se segue:

    • Se as palavras-chave COPY GRANTS forem usadas, então o novo objeto herda qualquer privilégio de acesso explícito concedido na tabela original, mas não herda qualquer futura concessão definida para o tipo de objeto no esquema.

    • Se as palavras-chave COPY GRANTS não são utilizadas, então o novo clone do objeto não herda nenhum privilégio de acesso explícito concedido na tabela original, mas herda qualquer concessão futura definida 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.

  • 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.

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

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

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

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 sobre colonagem com Time Travel (somente bancos de dados, esquemas e tabelas)

  • 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 secundários (por exemplo, tabelas em esquemas clonados ou banco de dados) foram purgados.

      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

Clonar uma tabela como ela existia imediatamente antes da execução da instrução especificada (isto é, ID da consulta):

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