AthenaではIcebergのTagを作れないが参照はできる
株式会社モリサワではデータレイクにIcebergテーブルを採用し、Athenaで分析を行っています。弊社ではDynamoDBからS3へのZeroETLによる連携の検証を行っており、特定のスナップショットを残すためにこのTag機能を利用しようとしました。ところが、AthenaではTagの作成がサポートされていません。では、別の手段でTagを作成した場合、Athenaから参照することはできるのでしょうか? 本記事ではその検証の過程と結果を紹介します。
Tagging
IcebergではTagという機能があり、スナップショットに名前をつけることができます。Tagをつけることで指定の期間スナップショットが保持されるため、監査などの目的で特定の履歴データを保持することに役立ちます。
Tagは以下のSQL文で簡単につけられます。
ALTER TABLE example_database.example_table CREATE TAG example_tag
AthenaではTagの付与がサポートされていない
このTagをつける機能は現時点ではAthenaでサポートされていません。そのためか公式ドキュメントでもスナップショットのIDを用いたバージョントラベル(Version Travel)クエリについては記載があるものの、Tagについては触れられていません。また、versionパラメーターにはbigintを指定するようにも記載されています。
Tagの参照はできそう
一方で、存在しないTagを参照するクエリを実行してみると、
INVALID_ARGUMENTS: Cannot find snapshot with reference name: non_exist_tag
というエラーが返ります。bigint型の不整合ではなく、reference nameが見つからないことが原因で失敗しています。つまり、Tagさえ存在すれば参照できそうに見えます。

GlueジョブでTagを作成してAthenaから参照する
エラーメッセージからすると、別の手段でTagをつければAthenaからTagを参照してクエリできそうです。AthenaからはTagをつけることはできなかったため、手軽にTagをつけられるGlueジョブのSpark上でTagをつけてみます。Glueジョブの中で以下を実行してTagを付与します。
spark.sql("""
ALTER TABLE glue_catalog.default.test_iceberg_tag
CREATE TAG v1_0
""")
以下のクエリでメタデータを参照すれば、Tagが正しく作成されていることがわかります。
SELECT * FROM "test_iceberg_tag$refs"

Tagを参照して以下のようにクエリしてみます。
SELECT * FROM test_iceberg_tag FOR VERSION AS OF 'v1_0'
データが正しくクエリできました。

まとめ
AthenaからIcebergのTagを作成できない制約に対し、GlueジョブでTagを作成することでAthenaからTagを参照してVersion Travelクエリが正しく動作することを確認できました。ただTagの管理はAthena単体では完結しないため、別の手段による管理が必要です。
公式ドキュメントではversionパラメーターにbigintを指定すると記載されていますが、実際にはTag名(文字列)でもVersion Travelクエリが動作します。なお、ドキュメントに記載のない挙動のため、今後のアップデートで変更される可能性がある点には注意してください。
Discussion