Databricks 環境で学ぶ Delta Lake タイムトラベル

記事タイトルとURLをコピーする

アプリケーションサービス本部の鎌田 (義) です。

データレイクで使用されるオープンテーブルフォーマットである Delta Lake, Apache Iceberg, Apache Hudi が提供する代表的な機能として以下があります。

  • ACID トランザクション
  • タイムトラベル
  • スキーマ強制と進化

本稿では、 Databricks が利用する Delta Lake におけるタイムトラベル機能について掘り下げます。

タイムトラベル機能とは

Delta Lake テーブルの過去の任意の時点の状態を再構築したり、閲覧したり、復元したりできる強力な機能です。

タイムトラベルの利点

  • 正確な監査 - テーブルに対するすべての操作(追加・削除・更新)は、最終的に相殺された場合でもトランザクションログに記録されるため、正確な監査が可能です。

  • 過去データへのアクセス - 過去の任意の時点でのテーブルの状態を正確に再構築できます。

  • データの復元と回復 - 誤ってデータが削除されたり、破損したりした場合でも、タイムトラベルを使用してテーブルを以前のバージョンに復元できます。

Delta Lake の構成

Delta Lake テーブルでは以下の構成でファイルが格納されています。

https://www.databricks.com/blog/2019/08/21/diving-into-delta-lake-unpacking-the-transaction-log.html

Delta Lake におけるタイムトラベル機能のカギを握るのは、トランザクションログ (_delta_log) です。 Delta Lake テーブルを作成するとトランザクションログが自動的に_delta_logサブディレクトリ内に000000.jsonが作成され、 以降の変更は000001.json, 000002.jsonといった具合で昇順で生成されます。

トランザクションログには、テーブルの元の状態から現在の状態に至るまでの詳細な手順がステップバイステップで記載されています。そのため、元のテーブルから開始し、その時点より前のコミットのみを処理することで、任意の時点のテーブルの状態を再現できます。
Diving Into Delta Lake: Unpacking The Transaction Log

Databricks でタイムトラベル機能を検証

公式チュートリアル に沿って、機能を体験してみます。

※補足
本記事では、公式チュートリアルで使用されている Kaggle の People10m データセットを利用します。 2025 年 7 月時点でダウンロードしたところ 1,000 万件ではなく、1,000 件しかデータが含まれていませんでしたが、本稿で検証する範囲では十分であるため、これを利用します。

テーブル作成

Kaggle からダウンロードしたデータセットを Volume に配置し、 以下コマンドでテーブルを作成、Volume のデータをテーブルにコピーします。

CREATE OR REPLACE TABLE main.default.people_10m (
  id INT,
  firstName STRING,
  middleName STRING,
  lastName STRING,
  gender STRING,
  birthDate TIMESTAMP,
  ssn STRING,
  salary INT
);
  
COPY INTO main.default.people_10m
FROM '/Volumes/main/default/my-volume/export.csv'
FILEFORMAT = CSV
FORMAT_OPTIONS ( 'header' = 'true', 'inferSchema' = 'true' );

この時点で該当テーブルを管理しているバケットを確認してみると_delta_log/ディレクトリと Parquet ファイルが作成されていました。

_delta_log配下に JSON ファイルが二つ作成されていました。

Parquet ファイルにはデータの実体が格納されており、当然ですが直接ファイルの中身を確認するとデータを確認できました。

>>> df
       id firstName middleName    lastName gender           birthDate          ssn  salary
0       1    Pennie      Carry  Hirschmann      F 1955-07-02 04:00:00  981-43-9345   56172
1       2        An      Amira      Cowper      F 1992-02-08 05:00:00  978-97-8086   40203
2       3     Quyen     Marlen        Dome      F 1970-10-11 04:00:00  957-57-8246   53417
3       4   Coralie   Antonina     Marshal      F 1990-04-11 04:00:00  963-39-4885   94727
4       5    Terrie       Wava       Bonar      F 1980-01-16 05:00:00  964-49-8051   79908
..    ...       ...        ...         ...    ...                 ...          ...     ...
995   996     Erika    Kathlyn       Hurst      F 1991-01-30 05:00:00  928-46-9978   63758
996   997    Briana       Rema     Dziwisz      F 1989-04-16 04:00:00  975-88-5431   70978
997   998  Khadijah    Annabel     Pauleau      F 1982-12-07 05:00:00  926-28-3981   93078
998   999  Corrinne      Hilda      Davana      F 1955-12-06 05:00:00  939-63-9947   70754
999  1000     Twyla  Rosalinda       Goves      F 1983-10-03 04:00:00  909-50-8966   92470

[1000 rows x 8 columns]

データ追加/更新/削除

追加用のデータを作成し、people_10m テーブルにアップサート (更新または挿入) します。

CREATE OR REPLACE TEMP VIEW people_10m_updates (
  id, firstName, middleName, lastName, gender, birthDate, ssn, salary
) AS VALUES
  (9999998, 'Billy', 'Tommie', 'Luppitt', 'M', '1992-09-17T04:00:00.000+0000', '953-38-9452', 55250),
  (9999999, 'Elias', 'Cyril', 'Leadbetter', 'M', '1984-05-22T04:00:00.000+0000', '906-51-2137', 48500),
  (10000000, 'Joshua', 'Chas', 'Broggio', 'M', '1968-07-22T04:00:00.000+0000', '988-61-6247', 90000),
  (20000001, 'John', '', 'Doe', 'M', '1978-01-14T04:00:00.000+0000', '345-67-8901', 55500),
  (20000002, 'Mary', '', 'Smith', 'F', '1982-10-29T01:00:00.000+0000', '456-78-9012', 98250),
  (20000003, 'Jane', '', 'Doe', 'F', '1981-06-25T04:00:00.000+0000', '567-89-0123', 89900);
  
MERGE INTO main.default.people_10m
USING people_10m_updates
ON people_10m.id = people_10m_updates.id
WHEN MATCHED THEN UPDATE SET *
WHEN NOT MATCHED THEN INSERT *;

この時点で、カタログから履歴を確認してみるとこれまでの操作がバージョンとして保持されていることが分かります。

続いて、データ更新と削除を行います。

更新

UPDATE main.default.people_10m SET gender = 'Female' WHERE gender = 'F';
UPDATE main.default.people_10m SET gender = 'Male' WHERE gender = 'M';

削除

DELETE FROM main.default.people_10m WHERE birthDate < '1955-01-01'

改めて、ここまでのテーブルへの変更履歴を確認してみます。

DESCRIBE HISTORY main.default.people_10m

過去のバージョンを表示する (タイムトラベル)

過去のバージョンのテーブルにアクセスするには、version指定かtimestamp(日付 or タイムスタンプ形式の文字列) 指定でアクセスします。

SELECT * FROM main.default.people_10m VERSION AS OF 0
-- or
SELECT * FROM main.default.people_10m TIMESTAMP AS OF '2025-07-22T22:33:29.000+00:00'

または、@構文を用いての検索も可能です ※タイムスタンプは yyyyMMddHHmmssSSS 形式

SELECT * FROM main.default.people_10m@v0
SELECT * FROM main.default.people_10m@20250722223329000

DELETE 前の状態のテーブルを表示してみると、アップサート後の状態である 1,006 件のレコードが表示されました。

DELETE 前の状態にテーブルを復元 (RESTORE) し、最新テーブルを参照すると 1,006 件のレコードが表示されました。

RESTORE TABLE main.default.people_10m TO VERSION AS OF 4;

データ削除について

テーブルからデータを削除しても、すぐに物理的に削除されるわけではありません。 これにより、タイムトラベルの機能でデータ変更前、及び削除前のテーブルを参照することも可能です。

テーブルの履歴を保持する期間delta.logRetentionDuration = "interval <interval>はデフォルトで interval 30 days です。 また、現在のテーブルバージョンで参照されなくなったデータファイルを削除するために VACUUM が使用するしきい値delta.deletedFileRetentionDuration = "interval <interval>"はデフォルトで interval 7 days です。

この値はテーブル作成時または ALTER TABLE にて変更可能です。

VACUUM によって削除されたデータファイルに変更または削除されたレコードが含まれている場合、以降はレコードにアクセスできなくなります。 例えば、30 日間の履歴データにアクセスしたい場合はdelta.deletedFileRetentionDurationの値もdelta.logRetentionDurationに合わせて 30 日に設定する必要があります。

予測的最適化

予測的最適化 が有効となっている場合 VACUUM は自動的に行われます。

予測的最適化は、テーブル管理を自動化してくれる便利な機能です。 VACUUM の他にも OPTIMIZE, ANALYZE が予測的最適化が有効なテーブルに対して自動的に実行されます。 OPTIMIZE は小さなデータファイルが多数存在する場合読み取り性能の劣化に繋がる為、大きなデータファイルに最適化してくれます。

なお、予測的最適化の実行については、ドキュメントに以下の記載があります。

予測的最適化は、 ANALYZE、 OPTIMIZE、および VACUUM 操作からメリットが得られるテーブルを特定し、サーバレス コンピュート for ジョブを使用して実行するようにキューに入れます。
Unity Catalog マネージドテーブル向け予測最適化

予測的最適化が有効化となっているかは、以下のコマンドで確認可能です。

DESCRIBE (CATALOG | SCHEMA | TABLE) EXTENDED name

また、予測的最適化が実行された履歴はsystem.storage.predictive_optimization_operations_historyテーブルから確認できます。

おわりに

本記事では、Delta Lake の代表的な機能であるタイムトラベルについて、Databricks 環境での実際の検証を通して詳しく解説しました。

タイムトラベル機能は、単なる「過去のデータを見る」機能ではありません。 トランザクションログによる正確な監査、誤操作からの迅速な復旧、データの変更履歴の追跡など、企業のデータガバナンスにおいて極めて重要な価値を提供します。

最後まで読んでいただき、ありがとうございました。
Databricks, Delta Lake の魅力が少しでも伝われば幸いです。

参考

鎌田 義章 (執筆記事一覧)

2023年4月入社 アプリケーションサービス本部ディベロップメントサービス3課