❄️

Snowflakeで間違えて実行したクエリの前の状態に戻す

2022/09/29に公開

前書き

Snowflakeをデータウェアハウスとして利用してプロダクトを開発しているソフトウェアエンジニアです。
普段はSnowflakeに関係するデータ基盤の設計から開発などの業務を行なっています。

先日、チームメンバーから「〇〇テーブル内のデータをdeleteしてしまったのでどうすれば良いか」という連絡を受けて、データを復元する対応をしたときの内容を公開します。

Time Travel機能を使う

Snowflakeには「Time Travel」という優れた機能があります。

https://docs.snowflake.com/ja/user-guide/data-time-travel.html

Snowflake Time Travelでは、定義された期間内の任意の時点で履歴データ(つまり、変更または削除されたデータ)にアクセスできます。Time Travelは、次のタスクを実行するための強力なツールとして機能します。

つまり、Snowflakeのアカウント内のオブジェクトにはデータ保持期間というのが設定されており、その期間の中であれば任意の状態にオブジェクト(データベース・スキーマ・テーブルなど)の状態をもとに戻すことができる機能になります。

具体的な活用例として、

  • オブジェクトをdropしてしまった際に、undropを使って復元する
  • 特定のクエリ(insert, delete etc.)が実行される前の状態にテーブルの状態を戻す
  • 過去のオブジェクトの状態からクローンして、新しいオブジェクトを複製する

などに利用できます。

本題

今回の問題の「〇〇テーブル内のデータをdeleteしてしまったのでどうすれば良いか」に関して、「Time Travel」機能を使って、クエリが実行される前の状態に戻すという作業を行いました。

流れとしては、

  1. 失敗してしまったクエリIDを特定する
  2. 「Time Travel」を使ってクエリが実行される前の状態のテーブルに戻す

となります。

information_schemaにある、query_historyテーブルからQUERY_IDを確認し、QUERY_IDを使って、その前のテーブルの状態に戻していきます。

select * from table(snowflake.information_schema.query_history()) order by start_time desc limit 100;
-- 対象のクエリのQUERY_IDを探す

insert overwrite into ${database_name}.${schema_name}.{table_name}
select * from ${database_name}.${schema_name}.{table_name} 
before (statement => '${QUERY_ID}');

-- 正しく復元できたか確認
select * from ${database_name}.${schema_name}.{table_name};  

これで正しくデータを復元できました。

参考

https://docs.snowflake.com/ja/user-guide/data-time-travel.html#querying-historical-data

Discussion