[Snowflake] Storage lifecycle policyを使ってみた

2025/11にStorage lifecycle policyがGAになりましたね。

今までは利用頻度が少ないテーブルはS3にアンロードして、S3 Glacierなどに保存するケースが多かったのかと思います。

Storage lifecycle policyによってデータライフサイクル管理プロセスを構築することなく、簡単にデータをアーカイブや削除できるようになってデータマネジメントが楽になりそうですね。

今回はStorage lifecycle policyがどんなものか試したいと思います。

目次


Storage lifecycle policyとは

標準テーブルのライフサイクルを設定できる機能。

対象のテーブルに対してポリシーをアタッチすることで、ライフサイクルポリシーがバックグラウンドで実行される。

出典: Storage lifecycle policies | Snowflake Documentation

アーカイブTierは2種類あり、それぞれの違いは以下になります。

COOLCOLD
データ復元時間即時最大48時間
最低保持期間90日180日
ストレージコスト$4/TB/月$1/TB/月
データ復元コスト$30/TB$20/TB

その他にもデータ処理などコストがかかるみたいなので、詳しく知りたい場合はこちらのCreditConsumptionTable.pdfで確認するのがおすすめです。


実際に使ってみた

データの準備

SNOWFLAKE_SAMPLE_DATA.TPCH_SF1000.ORDERSテーブルを使います。

テーブル統計情報は以下の通りです。

  • レコード数:1,500,000,000
  • サイズ:48.6TB

データの準備

Storage lifecycle policyが実行された場合のテーブルのクラスタリング状態も知りたいため、テーブルに対してクラスタリングキーを設定しておく。

CREATE OR REPLACE DATABASE sand_db;
CREATE OR REPLACE SCHEMA storage_lifecycle_policy;

CREATE OR REPLACE TABLE orders CLUSTER BY (o_orderdate)
AS
SELECT *
FROM snowflake_sample_data.tpch_sf1000.orders
;

Storage lifecycle policyの作成

基本的にはポリシーの条件にn年前などの日付をするケースが多いですが、ここではシンプルに固定の日付を指定します。

ARCHIVE_TIERARCHIVE_FOR_DAYSを指定しない場合は、対象のデータはExpire(=削除)されます。

CREATE OR REPLACE STORAGE LIFECYCLE POLICY archive_policy
AS (o_orderdate DATE)
RETURNS BOOLEAN -> o_orderdate < '1995-01-01'
ARCHIVE_TIER = COOL
ARCHIVE_FOR_DAYS = 90;

テーブルにアタッチ

ALTER TABLE orders
ADD STORAGE LIFECYCLE POLICY archive_policy ON (o_orderdate);

実行前にアーカイブされうるレコードを確認しておきます。

SELECT COUNT(*) FROM orders
WHERE o_orderdate < '1995-01-01';
-- 683304954

ポリシーが実行された後

ポリシーの初回実行はアタッチ後から約1日経過してからになります。それ以降は日次でポリシーが実行されます。

それではStorage lifecycle policyがちゃんと実行されたか確認してみます。

SELECT * FROM
  TABLE(
    INFORMATION_SCHEMA.STORAGE_LIFECYCLE_POLICY_HISTORY(
      REF_ENTITY_NAME => 'sand_db.storage_lifecycle_policy.orders',
      REF_ENTITY_DOMAIN => 'table',
      TIME_RANGE_START => DATEADD('DAY', -1, CURRENT_TIMESTAMP()),
      RESULT_LIMIT => 100
    )
  );

-- {
--   "ARCHIVE": {
--     "end_time": "2025-12-05 06:54:03.588 -0800",
--     "rows_archived": 683304954,
--     "start_time": "2025-12-05 06:53:12.604 -0800",
--     "state": "SUCCEEDED"
--   },
--   "EXPIRE_ARCHIVE": {
--     "end_time": "2025-12-05 06:53:12.605 -0800",
--     "rows_expired": 0,
--     "start_time": "2025-12-05 06:53:12.605 -0800",
--     "state": "SUCCEEDED"
--   }
-- }

ポリシー通りにデータをアーカイブできてますね。

アーカイブしたデータを一覧で確認できるSQLコマンドが欲しいですね。


気をつけるべきこと

1. サブクエリがあると実行エラーになる

ポリシー条件のクエリにサブクエリが1つ以上ある場合、エラーになることがあります。

自分が試していた時にもサブクエリのあるポリシーの実行時にエラーになることがありました。

そのため、ポリシーには比較的単純な条件を指定するのがよさそうです。

"errorMessage": "SQL execution error: Internal error archiving data.",

ドキュメントにも記載がありました。

Including one or more subqueries in the policy body might cause errors. When possible, limit the number of subqueries, limit the number of JOIN operations, and simplify WHERE clause conditions.

2. TimeTravelとFaile-safeとの関係

アーカイブされても、データはTimeTravelやFail-safeの期間内はデータストレージに残り続けるため、それらのストレージコストがかかることに注意が必要です。

3. テーブルのデータクラスタへの影響

テーブルに自動クラスタリングを設定している場合はデータアーカイブ後に、マイクロパーティションの再編が実行されます。

データをアーカイブする場合だけでなく、Expireする場合も同じです。(Snowflakeサポートに確認済みです。)

実際に今回のケースでもアーカイブされた後、テーブルの自動クラスタリングが実行されていました。

対象のテーブルに自動クラスタリングを設定している場合は、アーカイブするごとに自動クラスタリングが実行されるのでクラスタリングコストにも注意が必要ですね。


最後に

2025/11にGAされたStorage lifecycle policyを試してみました。

データを定期的にアーカイブしたり古いデータを削除する場合は、別途プロセスを構築する必要があったのですが、Storage lifecycle policyを使えば楽に実現できそうですね。

GAされたばかりで、日本語のドキュメントが少ないのでぜひ参考になれば嬉しいです。


参考