[新機能]データベースのバックアップをACCOUNTADMINでも削除・編集不能に設定した上で取得できる「Snapshot」がパブリックプレビューとなりました
さがらです。
Snowflakeの新機能として、Snapshotがパブリックプレビューとなりました。
この機能を試してみたので、その内容についてまとめてみます。
Snapshotとは
Snapshotですが、ACCOUNTADMINでも削除不能に設定した上で、Snapshot取得時点のデータベース・スキーマ・テーブルのバックアップを取ることができる機能となっております。
Snapshot取得の際は都度すべてのデータの物理コピーを行うのではなく、クローンと同じくゼロコピーバックアップを行う仕様となっております。そのため対象のデータに変更がなければ、毎日Snapshotを取得していてもストレージコストが増えることはありません。
また、「ACCOUNTADMINでも削除不能に設定」がポイントで、Retention lockを付与したsnapshot policyを用いてSnapshotを作成することで、ACCOUNTADMINはもちろんSnowflakeサポートでも削除できないSnapshotを作成することができます。Legal holdという特定の期間だけ設定して、Legal holdが有効化している場合は誰もSnapshotを削除できない、という仕様にすることも可能です。(注意点として、Retention lockとLegal holdは、Business Critical以上のエディションで利用できます。)
逆に言うと、軽い気持ちで毎日たくさんの変更が行われるテラバイト級のテーブルを含むSnapshotをRetention lock含むEXPIRE_AFTER_DAYS=365
のようなsnapshot policyで作成すると、ストレージコストがとんでもないことになります。動作確認用の検証時にはEXPIRE_AFTER_DAYS=1
として検証することを強く推奨します。
Snapshotの制限について
公式Docに記載の制限事項からの抜粋ですが、以下の制限がありますのでご注意ください。
- snapshot policyの
RETENTION LOCK
の設定を変更することはできません。 - snapshot policyに
RETENTION LOCK
がある場合、有効期限を長くすることはできますが、短くすることはできません。 - スケジュールされたSnapshotの最小スケジュール間隔は「1時間(60分)」です。
また、パブリックプレビュー期間中の制限事項として、以下の内容についても言及がありました。こちらもご注意ください。
- Snapshotの最大保持期間は、Snapshotの取得スケジュールに応じて変わります。
- 60分~119分ごとのスケジュール: 最大90日
- 120分~23時間59分ごとのスケジュール: 最大180日
- 24時間以上ごとのスケジュール: 最大366日
- スケジュールなし: 最大3653日(約10年)
- 特定のオブジェクト(データベース、スキーマ、テーブル)に対して作成できるスナップショットセットは、それぞれ最大2つまでです。
- ただし、1つのテーブルが、そのテーブルが属するスキーマのセット、データベースのセットにそれぞれ含まれることは可能です。
- 一度snapshot setに適用したsnapshot policyは、後から削除することはできません。
Snapshotでバックアップできるオブジェクトについて
こちらも公式Docからの抜粋ですが、2025/8/19時点、Snapshotでバックアップできるオブジェクト、できないオブジェクトの一覧は以下となっております。
対応していないオブジェクトも多くありますので、「本機能はあくまでもテーブルのSnapshotを中心とした機能である」と捉えていたほうが間違いないと思います。
Snapshotに対応しているオブジェクト
- Tables
Permanent tables
Transient tables
Dynamic tables
- Table constraints
- Sequences
- Views
Views
Secure views
- File formats
- Stored procedures (SQL, Javascript, Python, Java, Scala)
- User-defined functions (UDFs / UDTFs) (SQL, Javascript, Python, Java, Scala)
- Tasks (復元後は一時停止状態になります)
- Policies (
Column-level security
,Row access policies
,Tag-based masking policies
のみ) - Grants
- Object tagging
- Alerts
- Network rules
Snapshotに対応していないオブジェクト
- Tables
Temporary tables
External tables
Hybrid tables
Apache Iceberg™ tables
Event tables
- Materialized views
- Stages (
Internal stages
,External stages
,Temporary stages
) - Streams
- Pipes
- Database roles
- Github repos
- Policies (
Aggregation policy
,Projection policy
など、上記でリストされているもの以外) - その他 (
Models
,Streamlits
,Cortex search services
など、比較的新しい機能の多く)
Snapshotのコストについて
こちらも公式Docからの抜粋ですが、Snapshotは設定すると、パブリックプレビューの機能でありますがコストが発生します。
- コンピュート費用: Snapshotの作成・復元時に、Snowflakeが管理するコンピュートが使用されます
- ストレージ費用: Snapshotのデータを保存しておくための保管料として、ストレージコストが発生します。
実際のストレージコストは、TABLE_STORAGE_METRICS viewかSNAPSHOT_STORAGE_USAGE viewで確認可能です。
その他の仕様について
より詳細な仕様については以下のドキュメントをご覧ください。legal holdsなどについても言及があります。
試してみた
適当に作成したデータベースについて、Snapshotを設定してみます。
検証環境は、AWS東京リージョン、Business Criticalエディションのトライアルアカウントです。
事前準備:Snapshot取得対象のデータベースの作成
以下のブログの3.Load data
のクエリを実行して、Snapshot取得対象のデータベースを作成しておきます。
必要なデータベース・スキーマの作成
Snapshotの管理用に、データベースとスキーマを作成します。
-- ACCOUNTADMINロールを使用
USE ROLE ACCOUNTADMIN;
-- 管理用のデータベースを作成
CREATE DATABASE IF NOT EXISTS admin;
-- ポリシーを格納する専用スキーマを作成
CREATE SCHEMA IF NOT EXISTS admin.snapshot_policies;
-- Snapshot setを格納する専用スキーマを作成
CREATE SCHEMA IF NOT EXISTS admin.snapshots;
Retention lock付きのSnapshot policyを作成
Retention lockを設けることで、誰も削除ができないSnapshot policyを作成します。
-- 作業場所をポリシー用スキーマに指定
USE SCHEMA admin.snapshot_policies;
-- Retention lock付きのSnapshot policyを作成
CREATE SNAPSHOT POLICY raw_db_retention_policy
WITH RETENTION LOCK
SCHEDULE = 'USING CRON 0 20 * * * UTC' -- 毎日20:00(UTC)に実行
EXPIRE_AFTER_DAYS = 1; -- Snapshot作成から1日後にSnapshotが削除可能に
※下図は余談ですが、Enterpriseエディションで実行するとしっかり弾かれますw
Snapshot setを作成
Snapshotのベースとなる、Snapshot setを作成します。作成するときに、先ほど作成したRetention lock付きのSnapshot policyを指定します。
-- 作業場所をSnapshot set用スキーマに指定
USE SCHEMA admin.snapshots;
-- Snapshot setを作成
CREATE SNAPSHOT SET raw_db_snapshots
FOR DATABASE RAW
WITH SNAPSHOT POLICY admin.snapshot_policies.raw_db_retention_policy;
手動でSnapshotを作成
今回は検証が目的のため、手動でSnapshotを作成します。
-- 手動でSnapshotを追加
ALTER SNAPSHOT SET admin.snapshots.raw_db_snapshots ADD SNAPSHOT;
Retention lockが効いているか動作確認
作成したSnapshotに対して、Retention Lockが効いているか動作確認します。実際には、ACCOUNTADMINでも削除ができないことを確認してみます。
まずは、作成したSnapshotのIDを確認します。すると、下図のようにIDが表示されるため、これをメモします。今回は710964d1-b9ed-4c87-a618-fe3f21dda0b3
という値でした。
-- 作成されたSnapshotの一覧とIDを表示
SHOW SNAPSHOTS IN SNAPSHOT SET admin.snapshots.raw_db_snapshots;
この値を用いて、Snapshotを削除するコマンドを実行してみます。すると、Retention lockが効いているおかげで、削除ができませんでした!
-- ACCOUNTADMINロールで削除を試みる
ALTER SNAPSHOT SET admin.snapshots.raw_db_snapshots
DELETE SNAPSHOT IDENTIFIER '710964d1-b9ed-4c87-a618-fe3f21dda0b3';
Snapshotから復元を試みる
Snapshotはデータに異常があるときの復元にも使用することができるので、試してみます。
まず、Snapshotを取ったRAW
データベースの中で、JAFFLE_SHOP
スキーマを削除します。
-- JAFFLE_SHOPスキーマを削除
DROP SCHEMA RAW.JAFFLE_SHOP;
-- スキーマが消えたことを確認
SHOW SCHEMAS IN DATABASE RAW;
次に、先程確認したSnapshotのIDを用いて以下のコマンドを実行して、SnapshotからRAW
データベースを復元します。ちゃんと削除したJAFFLE_SHOP
スキーマもあることがわかります。
-- スナップショットIDを使って、データベース全体を新しい名前で復元
CREATE DATABASE RAW_RESTORED
FROM SNAPSHOT SET admin.snapshots.raw_db_snapshots
IDENTIFIER '710964d1-b9ed-4c87-a618-fe3f21dda0b3';
-- 削除したスキーマがあることを確認
SHOW SCHEMAS IN DATABASE RAW_RESTORED;
スキーマの削除を行ってしまったRAW
データベースと、復元したRAW_RESTORED
をSwapして、復元完了です!(Swap後、RAW_RESTORED
は削除しても問題ありません。)
-- 現在のRAWデータベースと、復元したRAW_RESTOREDデータベースを入れ替える
ALTER DATABASE RAW SWAP WITH RAW_RESTORED;
-- 削除したスキーマがあることを確認
SHOW SCHEMAS IN DATABASE RAW;
参考までに、復元後もスナップショットは消えずに残り続けます。
おまけ:データベースのSnapshotからスキーマの復元はできるのか?
データベースのSnapshotにはスキーマも含まれているので、データベースのSnapshotからスキーマの復元はできるのか?も試してみたのですが、下図の通りエラーとなりました。
CREATE SCHEMA RAW.JAFFLE_SHOP_RESTORED
FROM SNAPSHOT SET admin.snapshots.raw_db_snapshots
IDENTIFIER '710964d1-b9ed-4c87-a618-fe3f21dda0b3';
最後に
Snowflakeの新機能として、Snapshotがパブリックプレビューとなったので試してみました。
Retention lockにはBusiness Critical以上のエディションが必要ですが、データの改ざんができない形でデータのバックアップを保持できるのはこれまでのSnowflakeでは出来なかったので、ありがたい機能ではないでしょうか!クローンと同じくゼロコピーの仕様になっているので、データの更新が少ない場合はそこまでストレージコストがかからないのも嬉しいですね!
ぜひご活用ください!