ストリームの紹介

このトピックでは、ストリームを使用した変更データキャプチャの重要な概念を紹介します。

このトピックの内容:

オフセットストレージ

ストリームは、作成されると、特定の時点(呼称: オフセット)をオブジェクトの現在のトランザクションバージョンとして初期化することにより、ソースオブジェクト(例: テーブル、外部テーブル、またはビューの基になるテーブル)内にあるすべての行の初期スナップショットを論理的に取得します。ストリームで使用される変更追跡システムは、このスナップショットの取得後にコミットされた DML 変更に関する情報を記録します。変更レコードは、変更前後の行の状態を提供します。変更情報は、追跡されるソースオブジェクトの列構造を反映し、各変更イベントを説明する追加のメタデータ列を含みます。

ストリーム自体には、テーブルデータが 含まれない ことに注意してください。ストリームは、ソースオブジェクトのオフセットのみを保存し、ソースオブジェクトのバージョン管理履歴を活用して CDC 記録を返します。テーブルの最初のストリームが作成されると、非表示の列のペアがソーステーブルに追加され、変更追跡メタデータの保存が開始されます。これらの列は少量のストレージを消費します。ストリームのクエリ時に返される CDC レコードは、ストリームに保存されている オフセット と、テーブルに保存されている 変更追跡メタデータ の組み合わせに依存します。ビューのストリームの場合、これらのテーブルに非表示の列を追加するには、ビューと基になるテーブルに対して変更追跡を明示的に有効にする必要があることに注意してください。

ストリームをブックマークと考えると便利な場合があります。ブックマークは、ブックのページ(つまり、ソースオブジェクト)の特定の時点を示します。ブックマークは破棄でき、他のブックマークをブックのさまざまな場所に挿入できます。同様に、ストリームはドロップして、同じまたは異なる時点に作成された他のストリームにより(異なる時間に連続してストリームを作成するか、 Time Travel を使用)、同じまたは異なるオフセットでオブジェクトのために変更記録を消費することができます。

CDC 記録のコンシューマーの一例は、 データパイプライン です。このパイプラインでは、最後の抽出以降に変更されたステージングテーブルのデータのみが変換され、他のテーブルにコピーされます。

テーブルのバージョン管理

1つ以上の DML ステートメントを含むトランザクションがテーブルにコミットされるたびに、新しいテーブルバージョンが作成されます。これは、次のテーブルタイプに適用されます。

  • 標準テーブル

  • ディレクトリテーブル

  • 外部テーブル

  • ビューの基になるテーブル

テーブルのトランザクション履歴では、ストリームオフセットは2つのテーブルバージョンの間にあります。ストリームをクエリすると、オフセット後および現在の時刻以前にコミットされたトランザクションによって発生した変更が返されます。

次の例は、タイムラインに10のコミットされたバージョンを持つソーステーブルを示しています。ストリーム s1 のオフセットは、現在、テーブルバージョン v3v4 の間です。ストリームがクエリ(または消費)されると、返されるレコードには、テーブルタイムラインのストリームオフセットの直後のバージョンであるテーブルバージョン v4 から、タイムラインの最新のコミット済みテーブルバージョンである v10 までのすべてのトランザクションが含まれます。

Stream offset example

ストリームは、現在のオフセットから現在のバージョンのテーブルへの最小限の変更セットを提供します。

複数のクエリは、オフセットを変更することなく、ストリームから同じ変更データを独立して使用できます。ストリームは、DML トランザクションで使用される場合に のみ オフセットを進めます。この動作は、明示的トランザクションと 自動コミット トランザクションの両方に適用されます。(デフォルトでは、DML ステートメントが実行されると、自動コミットトランザクションが暗黙的に開始され、ステートメントの完了時にトランザクションがコミットされます。この動作は AUTOCOMMIT パラメーターで制御されます)。明示的なトランザクション内であっても、ストリームをクエリするだけではオフセットは進みません。ストリームの内容は、 DML ステートメント内で消費する必要があります。

注釈

DML 操作内で変更データを消費せずに、ストリームのオフセットを現在のテーブルバージョンに進めるには、次のいずれかのアクションを実行します。

  • ストリームを再作成します(CREATE OR REPLACE STREAM 構文を使用)。

  • 現在の変更データを仮テーブルに挿入します。INSERT ステートメントでストリームをクエリしますが、すべての変更データ(例: WHERE 0 = 1)を除外する WHERE 句を含めます。

SQL ステートメントが明示的なトランザクション内でストリームをクエリすると、ストリームはステートメントが実行されたときではなく、トランザクションが開始されたときのストリームアドバンスポイント(つまり、タイムスタンプ)でクエリされます。この動作は、DML ステートメントと、既存のストリームの行を新しいテーブルに取り込む CREATE TABLE ... AS SELECT (CTAS)ステートメントの両方に関係します。

ストリームから選択する DML ステートメントは、トランザクションが正常にコミットされる限り、ストリーム内のすべての変更データを消費します。複数のステートメントがストリーム内の同じ変更レコードにアクセスするようにするには、それらを明示的なトランザクションステートメント(BEGIN .. COMMIT)で囲みます。これにより、ストリームがロックされます。DML は並列トランザクションでのソースオブジェクトの更新は、変更追跡システムによって追跡されますが、明示的なトランザクションステートメントがコミットされ、既存の変更データが消費されるまでストリームを更新しません。

反復可能な読み取り分離

ストリームは反復可能な読み取り分離をサポートします。反復可能読み取りモードでは、トランザクション内の複数の SQL ステートメントがストリーム内の同じレコードセットを参照します。これは、テーブルでサポートされている読み取りコミットモードとは異なります。このモードでは、ステートメントは同じトランザクション内で実行された以前のステートメントによって行われた変更を、これらの変更がまだコミットされていない場合でも、確認します。

トランザクションでストリームによって返されるデルタレコードは、ストリームの現在位置からトランザクション開始時間までの範囲です。トランザクションがコミットされると、ストリーム位置はトランザクション開始時間まで進みます。それ以外の場合は、同じ位置に留まります。

次の例を考えてみましょう:

時間

トランザクション1

トランザクション2

1

トランザクションを開始します。

2

テーブル t1 のクエリストリーム s1 。ストリームは、現在の位置からトランザクション1の開始時刻までの変更データキャプチャレコード . を返します。ストリームが DML ステートメント . で使用されている場合、同時トランザクションによる変更を回避するためにストリームがロックされます。

3

テーブル t1 の行を更新します。

4

クエリストリーム s1Time 2 に使用されたときと同じストリームの状態を返します。

5

トランザクションをコミットします。ストリームがトランザクション内の DML ステートメントで消費された場合、ストリーム位置はトランザクション開始時間まで進みます。

6

トランザクションを開始します。

7

クエリストリーム s1。結果には、トランザクション1によってコミットされたテーブルの変更が含まれます。

トランザクション1内で、ストリーム s1 へのすべてのクエリは同じレコードセットを参照します。テーブル t1 へのDML 変更は、トランザクションがコミットされたときにのみストリームに記録されます。

トランザクション2で、ストリームへのクエリは、トランザクション1でテーブルに記録された変更を確認します。トランザクション1がコミットされる にトランザクション2が開始した場合、ストリームへのクエリは、ストリームの位置からトランザクション2の開始時刻までのストリームのスナップショットを返します。トランザクション1によってコミットされた変更は表示されません。

ストリーム列

ストリームには、実際のテーブルの列やデータではなく、ソースオブジェクトのオフセットが保存されます。クエリを実行すると、ストリームは履歴データにアクセスし、ソースオブジェクトと同じ形状(つまり、同じ列名と順序)で履歴データを返しますが、次の追加の列があります。

METADATA$ACTION

記録された DML 操作(INSERT、 DELETE)を示します。

METADATA$ISUPDATE

操作が UPDATE ステートメントの一部であったかどうかを示します。ソースオブジェクトの行の更新は、ストリーム内の DELETE および INSERT 記録のペアとして表され、メタデータ列の METADATA$ISUPDATE 値は TRUE に設定されます。

ストリームは2つのオフセットの違いを記録することに注意してください。行が追加され、現在のオフセットで更新された場合、デルタの変更は新しい行になります。 METADATA$ISUPDATE 行には FALSE 値が記録されます。

METADATA$ROW_ID

行の一意かつ不変の ID を指定します。これは、特定の行への変更を経時的に追跡するために使用できます。

ストリームのタイプ

次のストリーム型は、それぞれによって記録されたメタデータに基づいて使用できます。

標準

テーブル、ディレクトリテーブル、またはビューのストリームでサポートされます。 標準(つまり、デルタ)ストリームは、挿入、更新、削除(テーブルの切り捨てを含む)を含む、ソースオブジェクトへのすべての DML 変更を追跡します。このストリーム型は、変更セットで挿入および削除された行で結合を実行して、行レベルのデルタを提供します。たとえば、実質的な効果として、テーブル内の2つのトランザクションポイントの間に挿入されてから削除された行は、デルタで削除されます(つまり、ストリームのクエリ時に返されない)。

注釈

標準ストリームは、地理空間データの変更データを取得できません。地理空間データを含むオブジェクトに追加専用ストリームを作成することをお勧めします。

追加のみ

標準テーブル、ディレクトリテーブル、またはビューのストリームでサポートされています。 追加専用ストリームは行挿入のみを追跡します。更新および削除操作(テーブルの切り捨てを含む)は記録されません。たとえば、10行がテーブルに挿入され、追加専用ストリームのオフセットが進む前にそれらの行の5が削除された場合、ストリームは10行を記録します。

追加専用ストリームは追加された行のみを返すため、抽出、ロード、変換(ELT)、および行の挿入のみに依存する類似のシナリオのパフォーマンスが、標準ストリームの場合よりもはるかに向上します。たとえば、追加専用ストリームの行が消費された直後にソーステーブルを切り捨てることができ、記録の削除は、次にストリームがクエリまたは消費されるときにオーバーヘッドに寄与しません。

挿入のみ

外部テーブルのストリームでのみサポートされます。 挿入のみのストリームは、行の挿入のみを追跡します。挿入されたセットから行を削除する削除操作(つまり、何もしない)は記録されません。例えば、任意の2つのオフセットの間で、外部テーブルによって参照されるクラウドストレージの場所からFile1が削除され、File2が追加された場合、ストリームはFile2の行のレコードのみを返します。標準テーブルの CDC データを追跡する場合とは異なり、Snowflakeはクラウドストレージ内のファイルの履歴記録にアクセスできません。

上書きまたは追加されたファイルは、基本的に新しいファイルとして処理されます。古いバージョンのファイルはクラウドストレージから削除されますが、挿入専用ストリームは削除操作を記録しません。ファイルの新しいバージョンがクラウドストレージに追加され、挿入専用ストリームは行を挿入として記録します。ストリームは、古いファイルバージョンと新しいファイルバージョンの差分を記録しません。 Azure AppendBlobs を使用している場合など、追加によって外部テーブルメタデータの自動更新がトリガーされない場合があることに注意してください。

データフロー

次の図は、ソーステーブルの行が更新されるときに標準ストリームの内容がどのように変化するかを示しています。DML ステートメントがストリームコンテンツを消費するたびに、ストリーム位置が進み、テーブルに対する次の DML の変更(つまり、 テーブルバージョン の変更)を追跡します。

Streams Example

データ保持期間と陳腐化

ストリームのオフセットが、ソーステーブル(またはソースビューの基になるテーブル)のデータ保持期間の外にある場合、ストリームは古くなります。ストリームが古くなると、未使用の変更レコードを含め、ソーステーブルの履歴データにアクセスできなくなります。テーブルの 新しい 変更レコードを追跡するには、ストリームを再作成します( CREATE STREAM を使用)。ストリームが古くなるのを防ぐには、テーブルの保持期間中にトランザクション内でストリームレコードを消費します。データ保持期間の詳細については、 Time Travelの理解と使用 をご参照ください。

注釈

この制限は、データ保持期間のないディレクトリテーブルまたは外部テーブルのストリームには適用 されません

さらに、共有テーブルまたはビューのストリームは、それぞれテーブルまたは基になるテーブルのデータ保持期間を延長しません。詳細については、 共有オブジェクトのストリーム をご参照ください。

テーブルのデータ保持期間が 14日未満 であり、ストリームが消費されていない場合、Snowflakeはこの期間を一時的に延長して、古くならないようにします。アカウントの Snowflake Edition に関係なく、期間はストリームのオフセットまで、デフォルトで最大14日まで延長されます。Snowflakeがデータ保持期間を延長できる最大日数は、 MAX_DATA_EXTENSION_TIME_IN_DAYS パラメータ値によって決定されます。ストリームが消費されると、データ保持期間の延長はテーブルのデフォルト期間に短縮されます。

次の表は、 DATA_RETENTION_TIME_IN_DAYS とMAX_DATA_EXTENSION_TIME_IN_DAYSの値の例を示し、古くなることを回避するためにストリームコンテンツを消費する頻度を示しています。

DATA_RETENTION_TIME_IN_DAYS

MAX_DATA_EXTENSION_TIME_IN_DAYS

X日でストリームを消費する

14

0

14

1

14

14

0

90

90

ストリームの現在の陳腐化ステータスを表示するには、 DESCRIBE STREAM または SHOW STREAMS コマンドを実行します。STALE_AFTER 列のタイムスタンプは、ストリームが古くなると現時点で予測される時期(または、タイムスタンプが過去の場合は古くなった時期)を示します。これは、ソースオブジェクトの延長されたデータ保持期間です。このタイムスタンプは、ソースオブジェクトの DATA_RETENTION_TIME_IN_DAYS または MAX_DATA_EXTENSION_TIME_IN_DAYS パラメーター設定の大きい方を現在のタイムスタンプに追加することによって計算されます。ストリームの変更データを消費すると、 STALE_AFTER タイムスタンプが先送りされます。ストリームからの読み取りは、 STALE_AFTER タイムスタンプの後、しばらくの間成功する可能性があることに注意してください。ただし、この期間中はいつでもストリームが古くなる可能性があります。STALE 列は、ストリームが実際にはまだ古くなっていない可能性があるものの、現在古くなっていると予想されるかどうか示します。

ストリームが古くなるのを防ぐために、 STALE_AFTER タイムスタンプの前に(つまり、ソースオブジェクトの延長されたデータ保持期間内に)変更データを定期的に使用することを強くお勧めします。

STALE_AFTER タイムスタンプが経過すると、ストリームに未消費の記録がない場合でも、ストリームは随時古くなる可能性があります。ソースオブジェクトの変更データがある場合でも、ストリームをクエリすると0個の記録が返される場合があることに注意してください。たとえば、追加専用ストリームは行の挿入のみを追跡しますが、更新および削除アクティビティは変更記録もソースオブジェクトに書き込みます。変更データを生成しないテーブル書き込みのあまり明確でない例は、再クラスタリングです。

ストリームの変更データを消費すると、介在するバージョンに変更データが含まれているかどうかに関係なく、そのオフセットが現在に進みます。

重要

  • オブジェクトを再作成すると(CREATE OR REPLACE TABLE 構文を使用)、その履歴はドロップされ、テーブルまたはビューのストリームも古くなります。さらに、ビューの基になるテーブルを再作成またはドロップすると、ビューのストリームが古くなります。

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

  • ソースオブジェクトの名前を変更しても、ストリームが壊れたり、古くなったりすることはありません。さらに、ソースオブジェクトがドロップされ、同じ名前で新しいオブジェクトが作成される場合、元のオブジェクトにリンクされているストリームは、新しいオブジェクトにリンク されません

ストリームの複数のコンシューマー

ユーザーには、オブジェクトの変更記録のコンシューマーごとに個別のストリームを作成することをお勧めします。「コンシューマー」とは、 DML トランザクションを使用してオブジェクトの変更記録を消費するタスク、スクリプト、またはその他のメカニズムを指します。このトピックで前述したように、ストリームは DML トランザクションで使用されるとオフセットを進めます。Time Travelが使用されていない限り、単一ストリーム内の変更データのさまざまなコンシューマーはさまざまなデルタを取得します。DML トランザクションを使用して、ストリーム内の最新のオフセットからキャプチャされた変更データが使用されると、ストリームはオフセットを進めます。次のコンシューマーは、変更データを使用できなくなります。オブジェクトの 同じ 変更データを使用するには、オブジェクトに複数のストリームを作成します。ストリームはソースオブジェクトのオフセットのみを保存し、実際のテーブル列のデータは保存 しません。したがって、大きなコストをかけずに、オブジェクトに対する任意の数のストリームを作成できます。

ビューのストリーム

ビューのストリームは、ローカルビューと、セキュアビューを含む、Snowflake Secure Data Sharingを使用して共有されるビューの両方をサポートします。現在、ストリームはマテリアライズドビューの変更を追跡できません。

ストリームは、次の要件を満たすビューに制限されます。

基になるテーブル
  • 基になるテーブルは、すべてネイティブテーブルである必要があります。

  • ビューは、次の操作のみを適用できます。

    • Projections

    • Filters

    • 内部結合またはクロス結合

    • UNION ALL

FROM 句のネストされたビューとサブクエリは、完全に展開されたクエリがこの要件テーブルの他の要件を満たしている限りサポートされます。

クエリを表示する

一般的な要件:

  • クエリは任意の数の列を選択できます。

  • クエリには、任意の数の WHERE 述語を含めることができます。

  • 次の操作を含むビューはまだサポートされていません。

    • GROUP BY 句

    • QUALIFY 句

    • FROM 句にないサブクエリ

    • 相関サブクエリ

    • LIMIT 句

関数:

  • 選択リストの関数は、システム定義のスカラー関数である必要があります。

変更追跡

基になるテーブルで変更追跡を有効にする必要があります。

ビューでストリームを作成する前に、ビューの基になるテーブルで変更の追跡を有効にする必要があります。手順については、 ビューと基になるテーブルの変更追跡の有効化 をご参照ください。

CHANGES 句:ストリームに対する読み取り専用の代替

ストリームの代わりに、Snowflakeは SELECT ステートメントの CHANGES 句を使用して、テーブルまたはビューの変更追跡メタデータのクエリをサポートします。CHANGES 句を使用すると、明示的なトランザクションオフセットを使用してストリームを作成しなくても、2つの時点間で変更追跡メタデータをクエリできます。 CHANGES 句を使用しても、オフセットは前倒し されません (つまり、レコードを使用)。複数のクエリにより、異なるトランザクションの開始と終了の間で変更追跡メタデータを取得できます。このオプションでは、 AT | BEFORE 句を使用してメタデータのトランザクションの開始点を指定する必要があります。変更追跡間隔のエンドポイントは、オプションの END 句を使用して設定できます。

ストリームは、現在のトランザクション テーブルバージョン を保存し、ほとんどのシナリオで CDC 記録の適切なソースです。任意の期間のオフセットを管理する必要があるまれなシナリオでは、 CHANGES 句を使用できます。

現在、変更追跡メタデータが記録される前に、次がtrueである必要があります。

テーブル

テーブルで変更追跡を有効にする(ALTER TABLE ... CHANGE_TRACKING = TRUE を使用)か、テーブルでストリームを作成します(CREATE STREAM を使用)。

ビュー

ビューとその基になるテーブルで変更の追跡を有効にします。手順については、 ビューと基になるテーブルの変更追跡の有効化 をご参照ください。

変更追跡を有効にすると、非表示の列のペアがテーブルに追加され、変更追跡メタデータの保存が開始されます。これら非表示の CDC データ列の値は、ストリーム メタデータ列 への入力を提供します。列は少量のストレージを消費します。

これらの条件のいずれかが満たされる前の期間では、オブジェクトの変更追跡メタデータは使用できません。

必要なアクセス権限

ストリームのクエリには、少なくとも次のロール権限を持つロールが必要です。

オブジェクト

権限

注意

データベース

USAGE

スキーマ

USAGE

ストリーム

SELECT

テーブル

SELECT

テーブルのみのストリーム。

ビュー

SELECT

ビューのみのストリーム。

外部ステージ

USAGE

ディレクトリテーブル(外部ステージ上)のみのストリーム

内部ステージ

READ

ディレクトリテーブル(内部ステージ)のみのストリーム

ストリームの請求

このトピックの データ保持期間と陳腐化 で説明したように、ストリームが定期的に消費されない場合、Snowflakeは、ソーステーブルまたはソースビューの基になるテーブルのデータ保持期間を 一時的に 延長します。テーブルのデータ保持期間が14日未満の場合、アカウントの Snowflakeエディション に関係なく、期間はストリームトランザクションオフセット より短く 、または14日(テーブルのデータ保持期間が14日未満の場合)に、バックグラウンドで延長されます。

拡張データ保持期間には追加のストレージが必要であり、これは毎月のストレージ料金に反映されます。

ストリームに関連する主なコストは、仮想ウェアハウスがストリームをクエリするために使用する処理時間です。これらの料金は、なじみのあるSnowflakeクレジットとして請求書に表示されます。

最上部に戻る