[調査報告] Amazon Athena Icebergテーブルスキーマの変更を検証してみました!

[調査報告] Amazon Athena Icebergテーブルスキーマの変更を検証してみました!

Clock Icon2024.10.21

AWS事業本部コンサルティング部の石川です。Amazon AthenaのIcebergテーブルスキーマ変更機能の挙動についてデータファイルのレベルで、実際に動作確認を行いましたので、その結果をご報告いたします。

Icebergテーブルのスキーマの進化(Schema Evolution)

Amazon AthenaのIcebergテーブルは、一般的なDBのようにテーブルのカラムの追加、変更、削除が可能です。その柔軟さからApache Icebergでは、スキーマ進化(Schema Evolution) と呼び、単純なカラムの変更、追加、削除以上の優れた機能を提供します。カラムの追加、変更、削除すると、その変更を適用するタイミングはいつで、大きなテーブルを対象にしたときにどのような影響が生じるのかなど、実際の運用面では挙動を把握する必要があります。

そこで、今回は、Icebergテーブルスキーマの進化を参考に、以下の操作について検証しました。

  • カラムの追加(ALTER TABLE ADD COLUMNS)
  • カラムの削除(ALTER TABLE DROP COLUMN)
  • カラムの変更(ALTER TABLE CHANGE COLUMN)

それでは、各操作の結果を見ていきましょう。

ALTER TABLE ADD COLUMNS

既存のテーブルに新しいカラムを追加する操作を行いました。

ALTER TABLE ssbgzdb_tsv.customer_sevo ADD COLUMNS (col_bottom string);

検証用テーブル

下記のように検証用テーブルcustomer_sevoを作成して、そのテーブルに初期データを投入しています。

-- DROP TABLE ssbgzdb_tsv.customer_sevo;
CREATE TABLE ssbgzdb_tsv.customer_sevo (
  c_custkey int,
  c_name string,
  c_address string,
  c_city string,
  c_nation string,
  c_region string,
  c_phone string,
  c_mktsegment string)
LOCATION 's3://cm-test-20241020/ssbgz_tsv/customer_sevo'
TBLPROPERTIES (
  'table_type'='iceberg'
);

INSERT INTO ssbgzdb_tsv.customer_sevo
SELECT * FROM ssbgzdb_tsv.customer_ib;

SELECT COUNT(*) FROM ssbgzdb_tsv.customer_ib;
-- 3000000

上記のテーブルの全てファイル数を合計したデータサイズは、96736607バイトです。

% aws s3 ls s3://cm-test-20241020/ssbgz_tsv/customer_sevo --recursive --sum 
2024-10-20 22:57:59   93659497 ssbgz_tsv/customer_sevo/data/6oU-WQ/20240306_135749_00126_z6eb5-975cb51e-4bd7-4b8e-8805-1adb53252f65.parquet
2024-10-20 18:00:46    3060966 ssbgz_tsv/customer_sevo/data/P0iKaQ/20240306_090017_00032_4xju6-8075927f-b65f-4818-aa0e-fd2e1e858e67.parquet
2024-10-20 22:57:12       1717 ssbgz_tsv/customer_sevo/metadata/00000-d7214be4-dcb6-4d01-99ea-32e05bf99009.metadata.json
2024-10-20 22:58:01       2860 ssbgz_tsv/customer_sevo/metadata/00001-ce217406-e9a3-4ada-8598-8a3b641b256d.metadata.json
2024-10-20 22:58:01       7291 ssbgz_tsv/customer_sevo/metadata/e0b3cc79-d8dc-4ea0-b959-be1f9acd53fc-m0.avro
2024-10-20 22:58:01       4276 ssbgz_tsv/customer_sevo/metadata/snap-4837344339604003165-1-e0b3cc79-d8dc-4ea0-b959-be1f9acd53fc.avro

Total Objects: 6
   Total Size: 96736607

カラム追加

検証用のテーブルcustomer_sevocol_bottomカラムを追加しました。

ALTER TABLE ssbgzdb_tsv.customer_sevo ADD COLUMNS (col_bottom string);
SELECT COUNT(*) FROM ssbgzdb_tsv.customer_sevo WHERE col_bottom IS NULL;
-- 3000000
SELECT COUNT(*) FROM ssbgzdb_tsv.customer_sevo WHERE col_bottom = '';
-- 0

SHOW CREATE TABLE customer_sevo;
--- col_bottomカラムが追加されたことを確認
CREATE TABLE ssbgzdb_tsv.customer_sevo (
 c_custkey int,
 c_name string,
 c_address string,
 c_city string,
 c_nation string,
 c_region string,
 c_phone string,
 c_mktsegment string,
 col_bottom string)
LOCATION 's3://cm-test-20241020/ssbgz_tsv/customer_sevo'
TBLPROPERTIES (
 'table_type'='iceberg'
);

待たされることなく直ぐにカラムが追加されました。追加されたカラムには初期値としてNULLが設定されることが確認できました。上記のテーブルのデータサイズは、96740613バイト(4006バイトの増加)、つまりほとんど増えていません。

% aws s3 ls s3://cm-test-20241020/ssbgz_tsv/customer_sevo --recursive --sum 
2024-10-20 22:57:59   93659497 ssbgz_tsv/customer_sevo/data/6oU-WQ/20240306_135749_00126_z6eb5-975cb51e-4bd7-4b8e-8805-1adb53252f65.parquet
2024-10-20 18:00:46    3060966 ssbgz_tsv/customer_sevo/data/P0iKaQ/20240306_090017_00032_4xju6-8075927f-b65f-4818-aa0e-fd2e1e858e67.parquet
2024-10-20 22:57:12       1717 ssbgz_tsv/customer_sevo/metadata/00000-d7214be4-dcb6-4d01-99ea-32e05bf99009.metadata.json
2024-10-20 22:58:01       2860 ssbgz_tsv/customer_sevo/metadata/00001-ce217406-e9a3-4ada-8598-8a3b641b256d.metadata.json
2024-10-20 22:58:56       4006 ssbgz_tsv/customer_sevo/metadata/00002-3d4a2c2a-24d9-42e3-bab7-0cb13d336d87.metadata.json
2024-10-20 22:58:01       7291 ssbgz_tsv/customer_sevo/metadata/e0b3cc79-d8dc-4ea0-b959-be1f9acd53fc-m0.avro
2024-10-20 22:58:01       4276 ssbgz_tsv/customer_sevo/metadata/snap-4837344339604003165-1-e0b3cc79-d8dc-4ea0-b959-be1f9acd53fc.avro

Total Objects: 7
   Total Size: 96740613

追加したカラムにデータを更新

追加したカラムにUPDATE文でデータを更新します。

UPDATE ssbgzdb_tsv.customer_sevo SET col_bottom = 'x';

データの更新には時間がかかりました。

% aws s3 ls s3://cm-test-20241020/ssbgz_tsv/customer_sevo --recursive --sum 
2024-10-20 22:57:59   93659497 ssbgz_tsv/customer_sevo/data/6oU-WQ/20240306_135749_00126_z6eb5-975cb51e-4bd7-4b8e-8805-1adb53252f65.parquet
2024-10-20 18:00:46    3060966 ssbgz_tsv/customer_sevo/data/P0iKaQ/20240306_090017_00032_4xju6-8075927f-b65f-4818-aa0e-fd2e1e858e67.parquet
2024-10-20 23:02:06    3060966 ssbgz_tsv/customer_sevo/data/XTiF_Q/20240306_140145_00017_xhcgz-19c21c6a-1fa4-4ab5-85d5-319be0975204.parquet
2024-10-20 23:02:03   93662854 ssbgz_tsv/customer_sevo/data/z-rk1A/20240306_140145_00017_xhcgz-e9f93242-3c3f-4776-8129-6e34ca18b7a6.parquet
2024-10-20 22:57:12       1717 ssbgz_tsv/customer_sevo/metadata/00000-d7214be4-dcb6-4d01-99ea-32e05bf99009.metadata.json
2024-10-20 22:58:01       2860 ssbgz_tsv/customer_sevo/metadata/00001-ce217406-e9a3-4ada-8598-8a3b641b256d.metadata.json
2024-10-20 22:58:56       4006 ssbgz_tsv/customer_sevo/metadata/00002-3d4a2c2a-24d9-42e3-bab7-0cb13d336d87.metadata.json
2024-10-20 23:02:07       5901 ssbgz_tsv/customer_sevo/metadata/00003-b372d1d8-497f-4e67-a4ed-96be08e14162.metadata.json
2024-10-20 23:02:06       7356 ssbgz_tsv/customer_sevo/metadata/49f5a78f-f0ce-4880-afe9-68c0bf31c651-m0.avro
2024-10-20 23:02:06       7366 ssbgz_tsv/customer_sevo/metadata/6df1b724-3336-45b8-85d1-5bdfa71e2bd8-m0.avro
2024-10-20 22:58:01       7291 ssbgz_tsv/customer_sevo/metadata/e0b3cc79-d8dc-4ea0-b959-be1f9acd53fc-m0.avro
2024-10-20 22:58:01       4276 ssbgz_tsv/customer_sevo/metadata/snap-4837344339604003165-1-e0b3cc79-d8dc-4ea0-b959-be1f9acd53fc.avro
2024-10-20 23:02:06       4354 ssbgz_tsv/customer_sevo/metadata/snap-5312892158479628177-1-49f5a78f-f0ce-4880-afe9-68c0bf31c651.avro
2024-10-20 23:02:06       4348 ssbgz_tsv/customer_sevo/metadata/snap-778527561705377363-1-6df1b724-3336-45b8-85d1-5bdfa71e2bd8.avro

Total Objects: 14
   Total Size: 193493758

上記のテーブルのデータサイズは、193493758バイト(96753145バイトの増加)、ほぼ倍に増えています

恐らく、すべての行の更新に伴い、20240306_140145_00017_xxx.parquetファイルが2つ追加されたことが主な要因であり、既存のデータを更新したデータファイルが新たに作成されたと考えられます。

元のデータファイルが削除されるのは、履歴保持期間経過後にVACUUMを実行した際に開放されると考えられる。

結果

この操作の結果、以下のことが分かりました。

  • カラムの追加自体はすぐに反映されます。
  • データサイズはほとんど増加しません(今回の場合、4006バイトの増加)。
  • 新しいカラムにデータを追加すると、データサイズが大幅に増加します(今回は約96MBの増加)。

これは、カラム追加時にはメタデータの変更のみが行われ、実際のデータファイルの更新はデータ追加時に行われるためです。今回は、プリミティブなString型のカラムを追加しましたが、構造体や配列なども追加可能です。

ALTER TABLE DROP COLUMN

次に、既存のカラムを削除する操作を行いました。

ALTER TABLE customer_sevo DROP COLUMN c_address;

検証用テーブル

下記のように検証用テーブルcustomer_sevoを作成して、そのテーブルに初期データを投入しています。

-- DROP TABLE ssbgzdb_tsv.customer_sevo;
CREATE TABLE ssbgzdb_tsv.customer_sevo (
  c_custkey int,
  c_name string,
  c_address string,
  c_city string,
  c_nation string,
  c_region string,
  c_phone string,
  c_mktsegment string)
LOCATION 's3://cm-test-20241020/ssbgz_tsv/customer_sevo'
TBLPROPERTIES (
  'table_type'='iceberg'
);

INSERT INTO ssbgzdb_tsv.customer_sevo
SELECT * FROM ssbgzdb_tsv.customer_ib;

SELECT COUNT(*) FROM ssbgzdb_tsv.customer_ib;
-- 3000000

上記のテーブルの全てファイル数を合計したデータサイズは、93681518バイトです。

% aws s3 ls s3://cm-test-20241020/ssbgz_tsv/customer_sevo --recursive --sum 
2024-10-21 05:30:19   93665377 ssbgz_tsv/customer_sevo/data/WNQx5w/20240306_203008_00111_msics-e7b5c497-f469-4ac8-bb87-7d2a20006e5b.parquet
2024-10-21 05:30:02       1717 ssbgz_tsv/customer_sevo/metadata/00000-7035cb20-c76a-45a5-9b6a-3b46716a8646.metadata.json
2024-10-21 05:30:21       2860 ssbgz_tsv/customer_sevo/metadata/00001-264145f4-4e1e-453b-915a-e5ac61c778f6.metadata.json
2024-10-21 05:30:21       7291 ssbgz_tsv/customer_sevo/metadata/8d025d69-94b9-4af7-927f-0c3329bacbb2-m0.avro
2024-10-21 05:30:21       4273 ssbgz_tsv/customer_sevo/metadata/snap-4826230579802413408-1-8d025d69-94b9-4af7-927f-0c3329bacbb2.avro

Total Objects: 5
   Total Size: 93681518

カラム削除

検証用のテーブルcustomer_sevoc_addressカラムを削除しました。

ALTER TABLE customer_sevo DROP COLUMN c_address;
SHOW CREATE TABLE customer_sevo;
--- c_addressカラムが削除されたことを確認
CREATE TABLE ssbgzdb_tsv.customer_sevo (
 c_custkey int,
 c_name string,
 c_city string,
 c_nation string,
 c_region string,
 c_phone string,
 c_mktsegment string)
LOCATION 's3://cm-test-20241020/ssbgz_tsv/customer_sevo'
TBLPROPERTIES (
 'table_type'='iceberg'
);

待たされることなく直ぐにカラムが削除されました。データサイズは、93685317バイト(3799バイトの増加)、つまり微妙に増えています。実際に削除されるのは、履歴保持期間経過後にVACUUMを実行した際に開放されると考えられます。

% aws s3 ls s3://cm-test-20241020/ssbgz_tsv/customer_sevo --recursive --sum 
2024-10-21 05:30:19   93665377 ssbgz_tsv/customer_sevo/data/WNQx5w/20240306_203008_00111_msics-e7b5c497-f469-4ac8-bb87-7d2a20006e5b.parquet
2024-10-21 05:30:02       1717 ssbgz_tsv/customer_sevo/metadata/00000-7035cb20-c76a-45a5-9b6a-3b46716a8646.metadata.json
2024-10-21 05:30:21       2860 ssbgz_tsv/customer_sevo/metadata/00001-264145f4-4e1e-453b-915a-e5ac61c778f6.metadata.json
2024-10-21 05:52:31       3799 ssbgz_tsv/customer_sevo/metadata/00002-ee718a14-a75e-4efe-97b4-022c87818fba.metadata.json
2024-10-21 05:30:21       7291 ssbgz_tsv/customer_sevo/metadata/8d025d69-94b9-4af7-927f-0c3329bacbb2-m0.avro
2024-10-21 05:30:21       4273 ssbgz_tsv/customer_sevo/metadata/snap-4826230579802413408-1-8d025d69-94b9-4af7-927f-0c3329bacbb2.avro

Total Objects: 6
   Total Size: 93685317

この操作の結果、以下のことが判明しました。

  • カラムの削除はメタデータ上ですぐに反映されます。
  • しかし、実際のデータサイズはわずかに増加します(今回は3799バイトの増加)。
  • 実際のデータ削除は、履歴保持期間経過後にVACUUMを実行した際に行われると考えられます。

つまり、カラム削除操作は論理的な削除であり、物理的な削除はすぐには行われないということです。

ALTER TABLE CHANGE COLUMN

最後に、カラムの変更操作を検証しました。以下の3つの操作が可能であることを確認しました。

  • カラム名の変更
  • カラムの位置の変更
  • データ型の変更(ただし、互換性のある型間のみ)
ALTER TABLE customer_sevo CHANGE col_bottom col_top string
ALTER TABLE customer_sevo CHANGE COLUMN col_top col_top string COMMENT 'test column' AFTER c_name;
ALTER TABLE customer_sevo CHANGE col_xxx col_xxx bigint

検証用テーブル

下記のように検証用テーブルcustomer_sevoを作成して、そのテーブルに初期データを投入しています。

-- DROP TABLE ssbgzdb_tsv.customer_sevo;
CREATE TABLE ssbgzdb_tsv.customer_sevo (
  c_custkey int,
  c_name string,
  c_address string,
  c_city string,
  c_nation string,
  c_region string,
  c_phone string,
  c_mktsegment string)
LOCATION 's3://cm-test-20241020/ssbgz_tsv/customer_sevo'
TBLPROPERTIES (
  'table_type'='iceberg'
);

INSERT INTO ssbgzdb_tsv.customer_sevo
SELECT * FROM ssbgzdb_tsv.customer_ib;

SELECT COUNT(*) FROM ssbgzdb_tsv.customer_ib;
-- 3000000

カラムの変更

  • col_bottomcol_topカラム名変更
ALTER TABLE customer_sevo CHANGE col_bottom col_top string
  • c_nameを後ろの位置に異動
ALTER TABLE customer_sevo CHANGE COLUMN col_top col_top string COMMENT 'test column' AFTER c_name;
  • col_xxxをintからbigintにデータ型の変更
    • intからdoubleやstringへの変更はできません
ALTER TABLE customer_sevo ADD COLUMNS (col_xxx int);
ALTER TABLE customer_sevo CHANGE col_xxx col_xxx bigint

これらの操作は、データファイルの更新を伴わずに即時反映されることが分かりました。実際のデータの変更は、レコードが更新されるタイミングで行われるようです。

最後に

今回の検証を通じて、Amazon Athena のIcebergテーブルのスキーマ変更について、以下のことが明らかになりました。

  1. カラムの追加・削除・変更操作は、メタデータレベルですぐに反映されます。
  2. 実際のデータファイルの更新は、データの追加や更新時に行われます。
  3. カラムの削除では、物理的な削除はVACUUM実行時まで遅延されます。
  4. これらの特性により、スキーマ変更操作は高速で、大規模なデータ移動を伴わずに実行できます。

Amazon Athena Icebergテーブルのこれらの特性は、大規模なデータセットを扱う際に特に有用です。スキーマの進化を柔軟に行いながら、パフォーマンスへの影響を最小限に抑えることができます。

Athenaを使用している方々は、これらの機能を活用してデータモデルの進化をより効率的に管理できるでしょう。今後のプロジェクトでこの知見を活かしていただければ幸いです。

Share this article

facebook logohatena logotwitter logo

© Classmethod, Inc. All rights reserved.