クローニングに関する考慮事項

このトピックでは、Snowflakeのオブジェクト、特にデータベース、スキーマ、および非仮テーブルをクローンする際の重要な考慮事項について説明します。 DDL および DML トランザクション(ソースオブジェクト上)、Time Travel、データ保持期間などの要因は、オブジェクトのクローンに影響を与える可能性があります。

このトピックの内容:

クローンオブジェクトのアクセス制御権限

クローンオブジェクトは、ソースオブジェクト自体に付与された権限を保持しません(つまり、クローンはソースと同じ権限を自動的に持ちません)。システム管理者またはクローンされたオブジェクトの所有者は、新しく作成されたクローンに必要な権限を明示的に付与する必要があります。

ただし、ソースオブジェクトがソースに含まれる子オブジェクトのデータベースまたはスキーマである場合、クローンは対応する子オブジェクトに対して付与されたすべての権限を複製します。

  • データベースの場合、含まれるオブジェクトには、スキーマ、テーブル、ビューなどがあります。

  • スキーマの場合、含まれるオブジェクトには、テーブル、ビューなどがあります。

クローニングとSnowflakeオブジェクト

このセクションでは、特定のSnowflakeオブジェクトに関する特別なクローニングの考慮事項について説明します。

クローニングとステージ

個々の外部の名前付きステージをクローンできます。外部ステージは、外部クラウドストレージ内のバケットまたはコンテナーを参照します。外部ステージをクローニングしても、参照されるクラウドストレージには影響しません。

内部(つまりSnowflake)の名前付きステージは、クローン できません

データベースまたはスキーマをクローニングする場合、

  • クローニング操作の開始時にソースに存在していた外部の名前付きステージがクローニングされます。

  • テーブルはクローンされます。つまり、各テーブルに関連付けられた内部ステージもクローンされます。ソースデータベースまたはスキーマのテーブルステージに存在していたデータファイルは、クローンにコピーされません(つまり、クローンされたテーブルステージは空です)。

  • 内部の名前付きステージは、クローン されません

クローニングとパイプ

データベースまたはスキーマがクローンされる場合、内部(つまり、Snowflake)ステージを参照するソースコンテナーに含まれるパイプは、クローン されません

ただし、外部ステージを参照するパイプはクローンされます。これにより、次の動作が発生します。

  • ターゲットテーブルがパイプ定義の COPY ステートメントで完全修飾されている場合( データベース名.スキーマ名.テーブル名 または スキーマ名.テーブル名 の形式)、これにより、各パイプによってソースデータベースまたはスキーマのターゲットテーブルに重複データがロードされる可能性があります。

  • ターゲットテーブルが、パイプ定義で完全修飾されて いない 場合、データは、ソースおよびクローンされたデータベース/スキーマのターゲットテーブル(例: mytable)にロードされます。

パイプクローンのデフォルトの状態は次のとおりです。

  • AUTO_INGEST = FALSE の場合、クローンされたパイプはデフォルトで一時停止します。

  • AUTO_INGEST = TRUE の場合、クローンされたパイプは STOPPED_CLONED 状態に設定されます。この状態では、パイプは新しくステージングされたファイルの結果としてイベント通知を蓄積しません。パイプが明示的に再開されると、新しいイベント通知の結果としてトリガーされたデータファイルのみを処理します。

ALTER PIPE ... RESUME ステートメントを実行すると、どちらの状態のパイプクローンも再開できます。

クローニングとストリーム

現在、ソーステーブルとストリームを含むデータベースまたはスキーマのクローンが作成されると、(クローン内の)ストリーム内の未使用のレコードにアクセスできなくなります。この動作は、テーブルの Time Travel と一致しています。テーブルのクローンが作成される場合、テーブルクローンの履歴データは、クローンが作成された時間/時点で開始されます。

クローニングとタスク

タスクを含むデータベースまたはスキーマがクローンされると、クローン内のタスクはデフォルトで一時停止されます。タスクは個別に再開できます( ALTER TASK ... RESUME を使用)。

クローニングに対する DDL の影響

クローニングは高速ですが、瞬時ではありません。特に大きなオブジェクト(例:テーブル)の場合はそうです。そのため、クローニング操作の進行中にソースオブジェクトで DDL ステートメントが実行される場合(例:スキーマ内のテーブル名の変更)、変更がクローンに反映されない可能性があります。これは、 DDL ステートメントがアトミックであり、複数ステートメントトランザクションの一部ではないためです。

さらに、Snowflakeは、クローン作成操作の開始時にどのオブジェクト名が存在し、どの名前が変更されたかを記録しません。そのため、ソースの子オブジェクトの名前を変更(またはドロップして再作成)する DDL ステートメントは、進行中のクローニング操作と競合し、名前の競合を引き起こす可能性があります。

次の例では、 t_sales テーブルがドロップされ、また別のテーブルが変更され、親データベースのクローン作成中にドロップされたテーブルと同じ名前が付けられているため、エラーが発生します。

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.

ちなみに

クローニング操作中の名前解決の競合を避けるために、クローニング操作が完了するまでは、オブジェクトの名前をドロップされたオブジェクトが以前使用していた名前に変更しないことをお勧めします。

クローニングに対する DML およびデータ保持の影響

DATA_RETENTION_TIME_IN_DAYS パラメーターは、オブジェクトでTime Travelアクションを実行するためにSnowflakeが履歴データを保持する日数を指定します。Time Travelで保持されるデータにはテーブルレベルでストレージコストが発生するため、一部のユーザーは一部のテーブルでこのパラメーターを 0 に設定し、これらのテーブルのデータ保持を事実上無効にします(つまり、値が 0 に設定されている場合、Time Travel DML トランザクションで保持されているデータは消去され、追加のストレージコストはごくわずかです)。

特に大きなテーブルの場合、クローニング操作には時間がかかります。この期間中、 DML トランザクションはソーステーブルのデータを変更できます。その後、Snowflakeは、操作の開始時に存在していたテーブルデータをクローンしようとします。ただし、クローニング中に発生する DML トランザクションのデータがパージされると(テーブルの保持時間が 0 であるため)、操作を完了するためのデータがないため、次のようなエラーが生成されます。

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

ちなみに

回避策として、オブジェクトをクローニングする際に、次のベストプラクティスの どちらか をお勧めします。

  • 可能であれば、クローニング操作が完了するまで、ソースオブジェクト(またはその子)で DML トランザクションを実行しないでください。

  • これが不可能な場合は、クローニングを開始する前に、スキーマ(またはデータベース全体をクローンする場合はデータベース)のすべてのテーブルに DATA_RETENTION_TIME_IN_DAYS=1 を設定します。操作が完了したら、必要に応じて、ソース内にあるこれらのテーブルのパラメーター値を 0 にリセットしてください。

    クローンテーブルの値を 0 に設定することもできます(クローンテーブルに DML の変更を加える予定で、テーブルのTime Travelに追加のストレージコストをかけたくない場合)。

Time Travelを使用したクローニング(データベース、スキーマ、テーブル、およびストリームのみ)

このセクションでは、 Time Travel を使用して、過去の特定の時間/ポイントでオブジェクトをクローンする際に考慮する情報を提供します。

履歴オブジェクトのクローニング

ソースオブジェクトが AT | BEFORE 句で指定された時間/ポイントに存在しなかった場合は、エラーが返されます。

次の例では、CREATE TABLE ... CLONE ステートメントは、ソーステーブルが存在しなかった過去(30分前)の時点でクローンしようとします。

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.

指定された時間/時点で存在しなかった、クローンされたデータベースまたはスキーマ内のすべての オブジェクトはクローンされません。

パイプオブジェクトが(CREATE OR REPLACE PIPE構文を使用して)再作成された場合、または AT | BEFORE 句で指定された時点以降に削除された場合、クローン作成操作は失敗します。

履歴オブジェクトメタデータのクローニング

オブジェクトクローンは、 CREATE <オブジェクト> ... CLONE ステートメントが実行された時点、または Time Travel を使用して過去に指定された時間/ポイントで、現在のソースオブジェクトの 名前 および 構造 を継承します。オブジェクトクローンは、Time Travelが使用されているかどうかに関係なく、ステートメントの実行時にソースオブジェクトで現在使用されているコメントやテーブルクラスタリングキーなどの他のメタデータを継承します。

注釈

長いクローニング操作で一貫した動作を保証するために、CREATE <オブジェクト> ... CLONE ステートメントに AT または BEFORE 句が指定されていない場合、クローニング操作はステートメントが開始されたときに内部で AT 句の値をタイムスタンプとして設定します。