Remarques relatives au clonage

Ce chapitre fournit des remarques importantes sur le clonage d’objets dans Snowflake, en particulier sur le clonage de bases de données, de schémas et de tables (hors tables temporaires). Des facteurs tels que les transactions DDL et DML (sur l’objet source), Time Travel et les périodes de conservation des données peuvent affecter le clone d’objet.

Dans ce chapitre :

Privilèges de contrôle d’accès pour les objets clonés

Un objet cloné ne conserve aucun privilège accordé sur l’objet source lui-même (c’est-à-dire que les clones n’ont pas automatiquement les mêmes privilèges que leurs sources). Un administrateur système ou le propriétaire de l’objet cloné doit explicitement accorder tous les privilèges requis au clone nouvellement créé.

Cependant, si l’objet source est une base de données ou un schéma, pour les objets enfants (tables, vues, etc.) de la source, le clone réplique tous les privilèges accordés sur les objets enfants correspondants :

  • Pour les bases de données, les objets contenus incluent les schémas, les tables, les vues, etc.

  • Pour les schémas, les objets contenus incluent les tables, les vues, etc.

Clonage et objets Snowflake

Cette section décrit des considérations de clonage particulières concernant des objets Snowflake spécifiques.

Clonage et zones de préparation

Les règles suivantes s’appliquent aux zones de préparation de clonage ou aux objets qui contiennent des zones de préparation (c.-à-d. bases de données et schémas) :

  • Il est possible de cloner des zones de préparation nommées externes individuelles, mais pas des zones de préparation nommées internes.

  • Lors du clonage d’une base de données ou d’un schéma :

    • Les zones de préparation nommées externes présentes dans la source au démarrage de l’opération de clonage sont clonées.

    • Les tables sont clonées, ce qui signifie que leurs zones de préparation internes sont également clonées.

    • Les zones de préparation nommées internes ne sont pas clonées.

Indépendamment de la façon dont une zone de préparation a été clonée, le clone n’inclut pas les fichiers de la source, c’est-à-dire que toutes les zones de préparation clonées sont vides.

Clonage et canaux

Lorsqu’une base de données ou un schéma est cloné, tous les canaux du conteneur source qui font référence à une zone de préparation interne (c’est-à-dire Snowflake) ne sont pas clonés.

Cependant, tous les canaux faisant référence à une zone de préparation externe sont clonés. Cela entraîne le comportement suivant :

  • Si la table cible est pleinement qualifiée dans l’instruction COPY de la définition de canal (sous la forme nom_bdd.nom_schéma.nom_table ou nom_schéma.nom_table), cela peut entraîner le chargement de données en double dans la table cible de la base de données source ou du schéma par chaque canal.

  • Si la table cible n’est pas qualifiée entièrement dans la définition de canal, les données sont chargées dans la table cible (par exemple, mytable) et dans les bases de données/schémas sources et clonés.

Clonage et flux

Actuellement, lorsqu’une base de données ou un schéma contenant des tables source et des flux est cloné(e), tous les enregistrements non consommés dans les flux (dans le clone) sont inaccessibles. Ce comportement est cohérent avec Time Travel pour les tables. Si une table est clonée, les données historiques pour le clone de table commencent à l’heure/le moment où le clone a été créé.

Clonage et tâches

Quand une base de données ou un schéma contenant des tâches est cloné(e), les tâches du clone sont suspendues par défaut. Les tâches peuvent être reprises individuellement (avec ALTER TASK … RESUME).

Conséquence de DDL sur le clonage

Le clonage est rapide, mais pas instantané, en particulier pour les gros objets (par exemple les tables). Ainsi, si des instructions DDL sont exécutées sur des objets source (par exemple, renommer des tables dans un schéma) pendant que l’opération de clonage est en cours, les modifications peuvent ne pas être représentées dans le clone. La raison est que les instructions DDL sont atomiques et ne font pas partie des transactions à plusieurs instructions.

De plus, Snowflake n’enregistre pas les noms d’objets qui étaient présents lorsque l’opération de clonage a commencé et ceux qui ont changé de nom. Ainsi, les instructions DDL qui renomment (ou détruisent et recréent) les objets enfants sources sont en concurrence avec toute opération de clonage en cours et peuvent provoquer des conflits de nom.

Dans l’exemple suivant, la table t_sales est détruite, et une autre table est modifiée et reçoit le même nom que la table détruite pendant le clonage de la base de données mère, produisant une erreur :

CREATE OR REPLACE DATABASE staging_sales CLONE sales;

DROP TABLE sales.public.t_sales;

ALTER TABLE sales.public.t_sales_20170522 RENAME TO sales.public.t_sales;

002002 (42710): None: SQL compilation error: Object 'T_SALES' already exists.

Astuce

Pour éviter les conflits dans la résolution des noms au cours d’une opération de clonage, nous vous suggérons de ne pas renommer les objets par un nom précédemment utilisé par un objet détruit jusqu’à ce que le clonage soit terminé.

Conséquence de DML et de la conservation des donnée sur le clonage

Le paramètre DATA_RETENTION_TIME_IN_DAYS spécifie le nombre de jours pendant lesquels Snowflake conserve les données historiques pour effectuer des actions de Time Travel sur un objet. Comme les données conservées pour le Time Travel entraînent des coûts de stockage au niveau de la table, certains utilisateurs définissent ce paramètre sur 0 pour certaines tables, désactivant ainsi la conservation des données pour ces tables (c’est-à-dire que lorsque la valeur est définie sur 0, les données de Time Travel conservées pour les transactions DML sont purgées, entraînant des coûts de stockage supplémentaires négligeables).

Les opérations de clonage nécessitent du temps, en particulier pour les grandes tables. Pendant cette période, les transactions DML peuvent modifier les données d’une table source. Par la suite, Snowflake tente de cloner les données de la table telles qu’elles existaient lorsque l’opération a commencé. Cependant, si les données sont purgées pour les transactions DML qui se produisent pendant le clonage (car la durée de conservation de la table est 0), les données ne sont pas disponibles pour terminer l’opération, ce qui produit une erreur similaire à ce qui suit :

ProgrammingError occured: "000707 (02000): None: Data is not available." with query id None

Astuce

Comme solution, nous vous recommandons l’une des pratiques suivantes pour le clonage d’un objet :

  • S’abstenir, si possible, d’exécuter des transactions DML sur l’objet source (ou l’un de ses enfants) avant la fin de l’opération de clonage.

  • Si ce n’est pas possible, avant de commencer le clonage, définissez DATA_RETENTION_TIME_IN_DAYS=1 pour toutes les tables du schéma (ou de la base de données si vous clonez une base entière). Une fois l’opération terminée, n’oubliez pas de réinitialiser la valeur du paramètre sur 0 pour les tables de la source, si vous le souhaitez.

    Vous pouvez également définir la valeur sur 0 pour les tables clonées (si vous prévoyez d’apporter des modifications DML aux tables clonées et que vous ne souhaitez pas subir de frais de stockage supplémentaires pour Time Travel sur les tables).

Clonage à l’aide de Time Travel (bases de données, schémas et tables uniquement)

Cette section décrit les considérations à prendre en compte lors de l’utilisation de Time Travel pour cloner des objets à un moment ou à un point précis dans le passé.

Clonage d’objets historiques

Si l’objet source n’existait pas à l’instant ou au point spécifié dans la clause AT | BEFORE, une erreur est renvoyée.

Dans l’exemple suivant, une instruction CREATE TABLE … CLONE tente de cloner la table source à un moment dans le passé (30 minutes avant) où elle n’existait pas :

CREATE TABLE t_sales (numeric integer) data_retention_time_in_days=1;

CREATE OR REPLACE TABLE sales.public.t_sales_20170522 CLONE sales.public.t_sales at(offset => -60*30);

002003 (02000): SQL compilation error:
Object 'SALES.PUBLIC.T_SALES' does not exist.

Notez également que tout objet enfant qui n’existait pas au moment/au point spécifié n’est pas cloné.

Clonage de métadonnées d’objets historiques

Un objet cloné hérite de la définition de l’objet source au moment où l’instruction est exécutée. La définition comprend les noms d’objet, les commentaires, les colonnes de table, etc.

Dans l’exemple suivant, la table t_sales est renommée t_sales_20170522, puis les données sont insérées dans la table renommée. Le schéma contenant la table est cloné à un moment situé 30 minutes avant, avant que la table ne soit renommée et les données insérées. Le clone contient une table avec son nom actuel, et non pas le nom précédent, mais une image des données au moment spécifié :

CREATE OR REPLACE TABLE t_sales (numeric integer) data_retention_time_in_days=1;

INSERT INTO  t_sales (numeric)
VALUES (1),(2),(3);

ALTER TABLE sales.public.t_sales RENAME TO sales.public.t_sales_20170522;

INSERT INTO  t_sales_20170522 (numeric)
VALUES (4);

CREATE OR REPLACE SCHEMA sales.private CLONE sales.public at(offset => -60*30);

USE SCHEMA sales.private;

SHOW TABLES;

+-------------------------------+------------------+---------------+-------------+-------+---------+------------+------+-------+----------+----------------+
| created_on                    | name             | database_name | schema_name | kind  | comment | cluster_by | rows | bytes | owner    | retention_time |
|-------------------------------+------------------+---------------+-------------+-------+---------+------------+------+-------+----------+----------------|
| 2017-05-24 10:15:07.110 -0700 | T_SALES_20170522 | SALES         | PRIVATE     | TABLE |         |            |    4 |  1024 | SYSADMIN | 1              |
+-------------------------------+------------------+---------------+-------------+-------+---------+------------+------+-------+----------+----------------+

SELECT * FROM T_SALES_20170522;

+---------+
| NUMERIC |
|---------|
|       1 |
|       2 |
|       3 |
+---------+