はじめに
前回の記事では Iceberg のデータ更新フローと ACID 特性を説明しました。
更新フローの中で「スナップショット」という言葉が何度か登場しましたが、今回はこのスナップショットに焦点を当てます。
本記事では、
- スナップショットとは何か・いつ作成されるか
- タイムトラベルの仕組み
- タイムトラベルの使い方(クエリ・ロールバック)
を説明します。
スナップショットとは
スナップショットとは、ある時点におけるテーブルの完全な状態を表すメタデータです。
データファイルそのものではなく、「そのテーブルを構成するデータファイルの一覧」へのポインタを持っています。
各スナップショットは以下の情報を持っています。
- スナップショット ID:一意な識別子
- タイムスタンプ:コミットされた日時
- マニフェストリスト:このスナップショットを構成するマニフェストファイルの一覧
- 親スナップショット ID:一つ前のスナップショットへの参照
スナップショットはいつ作成されるか
INSERT・UPDATE・DELETE・MERGE などのデータ書き込み操作が コミットされるたびに 新しいスナップショットが作成されます。
スナップショットの履歴はメタデータファイルに蓄積されます。
操作のたびにスナップショットが積み重なっていくイメージ
snapshot-1(INSERT 5件) ← 最初の状態
↓
snapshot-2(INSERT 3件追加)
↓
snapshot-3(UPDATE 1件)
↓
snapshot-4(DELETE 2件) ← 現在の状態(current)
スナップショット一覧の確認
現在のスナップショット履歴は以下のクエリで確認できます。
SELECT * FROM demo.nyc.taxis.snapshots;
実行結果のイメージ:
| committed_at | snapshot_id | parent_id | operation |
|---|---|---|---|
| 2024-01-01 10:00:00 | 1234567890 | null | append |
| 2024-01-01 11:00:00 | 2345678901 | 1234567890 | append |
| 2024-01-01 12:00:00 | 3456789012 | 2345678901 | overwrite |
タイムトラベルの仕組み
Iceberg は既存のファイルを上書きせず、常に新しいファイルを追記します。
そのため、古いスナップショットが参照するデータファイルはストレージ上に残り続けます。
スナップショット ID またはタイムスタンプを指定することで、過去の任意の時点のデータをそのまま参照できます。
これがタイムトラベルです。
現在の参照(snapshot-4): data-1, data-2, data-3(data-4, data-5 を除いたもの)
過去の参照(snapshot-2): data-1, data-2
タイムトラベルの使い方
スナップショット ID を指定して参照
SELECT * FROM demo.nyc.taxis VERSION AS OF 1234567890;
タイムスタンプを指定して参照
SELECT * FROM demo.nyc.taxis TIMESTAMP AS OF '2024-01-01 11:00:00';
ロールバック
誤った更新をした場合など、テーブルを過去のスナップショットの状態に戻すことができます。
スナップショット ID を指定してロールバック:
CALL demo.system.rollback_to_snapshot('nyc.taxis', 1234567890);
タイムスタンプを指定してロールバック:
CALL demo.system.rollback_to_timestamp('nyc.taxis', TIMESTAMP '2024-01-01 11:00:00');
スナップショットの管理
スナップショットは蓄積し続けるため、古いスナップショットを定期的に削除するメンテナンスが必要です。
以下の手順で、指定した日時より古いスナップショットを削除できます。
CALL demo.system.expire_snapshots('nyc.taxis', TIMESTAMP '2024-01-01 00:00:00');
スナップショットを削除すると、そのスナップショットからのみ参照されていたデータファイルも削除対象となります。
タイムトラベルで過去データを参照したい期間を考慮しながら、保持期間を設定することが重要です。
おわりに
スナップショットが積み重なることでタイムトラベルが実現されています。
データを上書きしない設計が、過去参照・ロールバックといった強力な機能の基盤になっています。
次回は CoW(Copy-on-Write)と MoR(Merge-on-Read)について説明していきます。
乞うご期待!