Amazon S3、Azure、HDFS、またはローカルに保存された Apache Iceberg テーブルに対するテーブル形式インターフェイスを提供します。
構文
icebergS3(url [, NOSIGN | access_key_id, secret_access_key, [session_token]] [,format] [,compression_method] [,extra_credentials])
icebergS3(named_collection[, option=value [,..]])
icebergAzure(connection_string|storage_account_url, container_name, blobpath, [,account_name], [,account_key] [,format] [,compression_method])
icebergAzure(named_collection[, option=value [,..]])
icebergHDFS(path_to_table, [,format] [,compression_method])
icebergHDFS(named_collection[, option=value [,..]])
icebergLocal(path_to_table, [,format] [,compression_method])
icebergLocal(named_collection[, option=value [,..]])引数
引数の説明は、それぞれテーブル関数 s3、azureBlobStorage、HDFS、file の引数の説明と同様です。
format は Iceberg テーブル内のデータファイルのフォーマットを表します。
icebergS3 では、ClickHouse Cloud でロールベースのアクセスを行うための role_arn を渡すために、オプションの extra_credentials パラメータを使用できます。設定手順については、Secure S3 を参照してください。
戻り値
指定した Iceberg テーブル内のデータを読み取るための、指定した構造のテーブル。
例
SELECT * FROM icebergS3('http://test.s3.amazonaws.com/clickhouse-bucket/test_table', 'test', 'test')named collection を定義する
URL と認証情報を保存するための named collection を設定する例を以下に示します。
<clickhouse>
<named_collections>
<iceberg_conf>
<url>http://test.s3.amazonaws.com/clickhouse-bucket/</url>
<access_key_id>test</access_key_id>
<secret_access_key>test</secret_access_key>
<format>auto</format>
<structure>auto</structure>
</iceberg_conf>
</named_collections>
</clickhouse>SELECT * FROM icebergS3(iceberg_conf, filename = 'test_table')
DESCRIBE icebergS3(iceberg_conf, filename = 'test_table')データカタログの使用
Iceberg テーブルは、REST Catalog、AWS Glue Data Catalog、Unity Catalog など、さまざまなデータカタログと組み合わせて使用することもできます。
これらを使用するには、IcebergS3 エンジンでテーブルを作成し、必要な設定を指定します。
たとえば、MinIO ストレージで REST Catalog を使用する場合は次のとおりです。
CREATE TABLE `database_name.table_name`
ENGINE = IcebergS3(
'http://minio:9000/warehouse-rest/table_name/',
'minio_access_key',
'minio_secret_key'
)または、S3 と AWS Glue Data Catalog を併用する場合:
CREATE TABLE `my_database.my_table`
ENGINE = IcebergS3(
's3://my-data-bucket/warehouse/my_database/my_table/',
'aws_access_key',
'aws_secret_key'
)スキーマ進化
現時点では、CH を使用して、時間の経過とともにスキーマが変更された Iceberg テーブルを読み取ることができます。現在は、カラムの追加や削除、カラム順の変更が行われたテーブルの読み取りをサポートしています。また、値が必須のカラムを、NULL を許可するカラムに変更することもできます。さらに、単純型については、許可された型キャストとして次の変換をサポートしています。
- int -> long
- float -> double
- decimal(P, S) -> decimal(P', S) where P' > P.
現在のところ、ネストされた構造や、Array および Map 内の要素の型を変更することはできません。
パーティションプルーニング
ClickHouse は、Iceberg テーブルに対する SELECT クエリでパーティションプルーニングをサポートしており、無関係なデータファイルをスキップすることでクエリ性能を最適化できます。パーティションプルーニングを有効にするには、use_iceberg_partition_pruning = 1 を設定します。Iceberg のパーティションプルーニングの詳細については、https://iceberg.apache.org/spec/#partitioning を参照してください
タイムトラベル
ClickHouse は Iceberg テーブルでのタイムトラベルをサポートしており、特定のタイムスタンプまたはスナップショット ID を指定して過去のデータをクエリできます。
削除された行を含むテーブルの処理
ClickHouse は、position deletes および equality deletes を持つ Iceberg テーブルをサポートしています。equality deletes は v25.8 からサポートされています。
以下の削除方式は サポートされていません:
- 削除ベクター (v3 で導入)
基本的な使い方
SELECT * FROM example_table ORDER BY 1
SETTINGS iceberg_timestamp_ms = 1714636800000 SELECT * FROM example_table ORDER BY 1
SETTINGS iceberg_snapshot_id = 3547395809148285433注: 同じクエリ内で iceberg_timestamp_ms と iceberg_snapshot_id の両方のパラメータを指定することはできません。
重要な考慮事項
-
スナップショット は通常、次のタイミングで作成されます:
-
新しいデータがテーブルに書き込まれたとき
-
何らかのデータ コンパクション が実行されたとき
-
スキーマの変更では通常、スナップショットは作成されません - このため、スキーマ進化を経たテーブルで タイムトラベル を使用する際には、重要な挙動が生じます。
シナリオ例
これらのシナリオでは、外部の Iceberg writer によるスキーマ変更を Spark を使用して説明します。
シナリオ 1: 新しいスナップショットがない場合のスキーマ変更
次の一連の操作を考えてみましょう。
-- 2つのカラムを持つテーブルを作成する
CREATE TABLE IF NOT EXISTS spark_catalog.db.time_travel_example (
order_number bigint,
product_code string
)
USING iceberg
OPTIONS ('format-version'='2')
- - テ異なるタイムスタンプでのクエリ結果:
- ts1 & ts2: 元の 2 つのカラムのみが表示される
- ts3: 3 つのカラムがすべて表示され、1 行目の
priceは NULL になる
シナリオ 2: 履歴と現在のスキーマの違い
現時点でタイムトラベルクエリを実行すると、現在のテーブルとは異なるスキーマが表示されることがあります:
-- テーブルを作成する
CREATE TABLE IF NOT EXISTS spark_catalog.db.time_travel_example_2 (
order_number bigint,
product_code string
)
USING iceberg
OPTIONS ('format-version'='2')
-- テーブルに初期データを挿入する
INSERT INTO spark_catalog.db.time_travel_example_2 VALUES (2, 'Venus');
-- テーブルを変更して新しいカラムを追加する
ALTER TABLE spark_catalog.db.time_travel_example_2 ADD COLUMN (price double);
ts = now();
-- タイムスタンプ構文を使用して現時点のテーブルをクエリする
SELECT * FROM spark_catalog.db.time_travel_example_2 TIMESTAMP AS OF ts;
+------------+------------+
|order_number|product_code|
+------------+------------+
| 2| Venus|
+------------+------------+
-- 現時点のテーブルをクエリする
SELECT * FROM spark_catalog.db.time_travel_example_2;
+------------+------------+-----+
|order_number|product_code|price|
+------------+------------+-----+
| 2| Venus| NULL|
+------------+------------+-----+これは、ALTER TABLE では新しい スナップショット は作成されず、現在のテーブルでは Spark が スナップショット ではなく最新のメタデータファイルから schema_id の値を取得するために発生します。
シナリオ3: 履歴と現在のスキーマの違い
2つ目は、タイムトラベルを使っても、そのテーブルにまだデータが一度も書き込まれていなかった時点の状態は取得できないことです:
-- Create a table
CREATE TABLE IF NOT EXISTS spark_catalog.db.time_travel_example_3 (
order_number bigint,
product_code string
)
USING iceberg
OPTIONS ('format-version'='2');
ts = now();
-- Query the table at a specific timestamp
SELECT * FROM spark_catalog.db.time_travel_example_3 TIMESTAMP AS OF ts; -- Finises with error: Cannot find a snapshot older than ts.ClickHouse では、この挙動は Spark と同様です。Spark の Select クエリを ClickHouse の Select クエリに読み替えれば、同じように機能します。
メタデータファイルの特定
ClickHouseでicebergテーブル関数を使用する場合、システムはIcebergテーブルの構造を記述した適切なmetadata.jsonファイルを特定する必要があります。この特定プロセスは次のように機能します。
候補検索 (優先順)
- 直接パス指定:
*
iceberg_metadata_file_pathを設定すると、システムはこの正確なパスを Iceberg テーブルのディレクトリパスと組み合わせて使用します。
- この設定が指定されている場合、ほかのすべての解決用設定は無視されます。
-
テーブル UUID の照合: *
iceberg_metadata_table_uuidが指定されている場合、システムは次のように動作します:metadataディレクトリ内の.metadata.jsonファイルのみを対象にします- 指定した UUID と一致する
table-uuidフィールドを含むファイルに絞り込みます (大文字と小文字は区別されません)
-
デフォルト検索: *上記のいずれの設定も指定されていない場合、
metadataディレクトリ内のすべての.metadata.jsonファイルが候補になります
最新のファイルを選択する
上記のルールを使用して候補ファイルを特定した後、システムはその中から最新のものを判定します。
-
iceberg_recent_metadata_file_by_last_updated_ms_fieldが有効な場合: -
last-updated-msの値が最も大きいファイルが選択されます -
それ以外の場合:
-
バージョン番号が最も大きいファイルが選択されます
-
(バージョンは、
V.metadata.jsonまたはV-uuid.metadata.json形式のファイル名ではVとして表されます)
注: ここで言及している設定はすべてテーブル関数の設定 (グローバル設定やクエリレベルの設定ではありません) であり、以下に示すとおりに指定する必要があります。
SELECT * FROM iceberg('s3://bucket/path/to/iceberg_table',
SETTINGS iceberg_metadata_table_uuid = 'a90eed4c-f74b-4e5b-b630-096fb9d09021');注記: 通常、メタデータの解決は Iceberg カタログが行いますが、ClickHouse の iceberg テーブル関数 は S3 に保存されたファイルを Iceberg テーブルとして直接解釈するため、これらの解決ルールを理解しておくことが重要です。
メタデータキャッシュ
Iceberg テーブルエンジン と テーブル関数 は、マニフェストファイル、マニフェストリスト、metadata json の情報を保持するメタデータキャッシュをサポートしています。このキャッシュはメモリに保存されます。この機能は設定 use_iceberg_metadata_files_cache で制御されており、デフォルトで有効になっています。
別名
テーブル関数 iceberg は現在、icebergS3 の別名です。
仮想カラム
_path— ファイルのパス。型:LowCardinality(String)._file— ファイル名。型:LowCardinality(String)._size— ファイルサイズ (バイト単位) 。型:Nullable(UInt64). ファイルサイズが不明な場合、値はNULLです。_time— ファイルの最終更新時刻。型:Nullable(DateTime). 時刻が不明な場合、値はNULLです。_etag— ファイルの etag。型:LowCardinality(String). etag が不明な場合、値はNULLです。
Icebergテーブルへの書き込み
バージョン25.7以降、ClickHouse は書き込み可能なストレージバックエンド上の Iceberg テーブルの変更をサポートしています。
Iceberg テーブルを変更または保守する前に、allow_insert_into_iceberg 設定を有効にしてください。一部の操作には、以下で説明する追加の設定が必要です。
SET allow_insert_into_iceberg = 1;Icebergテーブルの作成
書き込み可能なバックエンドに新しいスタンドアロンのIcebergテーブルを作成するには、Icebergテーブルエンジンを使用し、スキーマを明示的に指定します。 書き込みでは、Parquet、Avro、ORC など、Iceberg仕様で定義されているすべてのデータフォーマットをサポートしています。
例
CREATE TABLE iceberg_writes_example
(
x Nullable(String),
y Nullable(Int32)
)
ENGINE = IcebergLocal('/home/scanhex12/iceberg_example/')注記: バージョンヒントファイルを作成するには、iceberg_use_version_hint 設定を有効にします。
metadata.json ファイルを圧縮する場合は、iceberg_metadata_compression_method 設定でcodec名を指定します。
INSERT
新しいテーブルを作成したら、通常の ClickHouse 構文を使用してデータを挿入できます。
例
INSERT INTO iceberg_writes_example VALUES ('Pavel', 777), ('Ivanov', 993);
SELECT *
FROM iceberg_writes_example
FORMAT VERTICAL;
Row 1:
─DELETE
ClickHouse は、merge-on-read フォーマットで余分な行を削除することにも対応しています。 このクエリは、position delete ファイル を含む新しいスナップショットを作成します。
例
ALTER TABLE iceberg_writes_example DELETE WHERE x != 'Ivanov';
SELECT *
FROM iceberg_writes_example
FORMAT VERTICAL;
Row 1:
─スキーマ進化
ClickHouse では、単純型 (Tuple、Array、Map 以外) のカラムを簡単に追加、削除、変更、または名前変更できます。
例
ALTER TABLE iceberg_writes_example MODIFY COLUMN y Nullable(Int64);
SHOW CREATE TABLE iceberg_writes_example;
┌コンパクション
ClickHouse は Iceberg テーブルのコンパクションをサポートしています。現在は、メタデータを更新しながら、position delete ファイル を data files にマージできます。以前のスナップショット ID とタイムスタンプは変更されないため、タイムトラベル機能も引き続き同じ値で利用できます。
使用方法:
SET allow_experimental_iceberg_compaction = 1
OPTIMIZE TABLE iceberg_writes_example;
SELECT *
FROM iceberg_writes_example
FORMAT VERTICAL;
Row 1:
─スナップショットの期限切れ処理
Iceberg テーブルでは、INSERT、DELETE、または UPDATE を実行するたびにスナップショットが蓄積されます。時間の経過とともに、これにより大量のスナップショットと、それに関連するデータファイルが生じる可能性があります。expire_snapshots コマンドは、古いスナップショットを削除し、保持されているどのスナップショットからも参照されなくなったデータファイルをクリーンアップします。
構文:
ALTER TABLE iceberg_table EXECUTE expire_snapshots(
['timestamp']
[, expire_before = 'timestamp']
[, retention_period = '3d']
[, retain_last = 100]
[, snapshot_ids = [1, 2, 3, 4]]
[, dry_run = 1]
);デフォルトでは、どのスナップショットを保持するかは 保持ポリシー (テーブルプロパティ min-snapshots-to-keep、max-snapshot-age-ms、および ref ごとのオーバーライド) によって決まります。snapshot_ids を指定すると、保持ポリシーは適用されず、リストされたスナップショットだけが削除対象として扱われます。
引数:
'timestamp'(位置引数) またはexpire_before = 'timestamp'— サーバーのタイムゾーンで解釈される日時文字列 (例:'2024-06-01 00:00:00') 。安全弁として機能し、timestamp-msがこの値以上のスナップショットは、保持ポリシーでは削除対象になる場合でも保護されます。snapshot_idsと組み合わせることもでき、その場合はリストされたスナップショットのうち、指定した timestamp と同時刻以降のものは削除されません。retention_period = '<duration>'— この呼び出しに限り、テーブルレベルのhistory.expire.max-snapshot-age-msを上書きします。この期間より古いスナップショット (現在時刻を基準に判定) が、削除候補になります。値は、1 つ以上の{number}{unit}の組を連結した期間文字列です。サポートされる単位:y(365 日) 、w(7 日) 、d(24 時間) 、h(60 分) 、m(60 秒) 、s(1 秒) 、ms(1 ミリ秒) 。単位は組み合わせ可能で、例:'3d'、'12h'、'1d12h30m'、'500ms'。retain_last = N— この呼び出しに限り、テーブルレベルのhistory.expire.min-snapshots-to-keepを上書きします。少なくともN個のスナップショットは、古さに関係なく常に保持されます。snapshot_ids = [id1, id2, ...]— リストされたスナップショット ID のみを削除対象にします (現在のスナップショット、ブランチ、またはタグから参照されているスナップショットを除く) 。このモードでは保持ポリシーは完全に無視され、retention_periodまたはretain_lastとは組み合わせられません。dry_run = 1— 何が削除対象になるかを計算し、新しいメタデータの書き込みやファイル削除を行わずにメトリクスを返します。
例:
SET allow_insert_into_iceberg = 1;
-- データを挿入してスナップショットを作成する
INSERT INTO iceberg_table VALUES (1);
INSERT INTO iceberg_table VALUES (2);
INSERT INTO iceberg_table VALUES (3);
-- 保持ポリシーのみを使用してスナップショットを期限切れにする
ALTER TABLE iceberg_table EXECUTE expire_snapshots();
-- 安全ヒューズを使用して期限切れにする: タイムスタンプより新しいスナップショットを保護する(位置引数構文)
ALTER TABLE iceberg_table EXECUTE expire_snapshots('2025-01-01 00:00:00');
-- 名前付き引数形式を使用した場合も同様
ALTER TABLE iceberg_table EXECUTE expire_snapshots(expire_before = '2025-01-01 00:00:00');
-- 1回の実行に限り保持パラメータを上書きする
ALTER TABLE iceberg_table EXECUTE expire_snapshots(retention_period = '3d', retain_last = 10);
-- 特定のスナップショットを明示的に期限切れにする
ALTER TABLE iceberg_table EXECUTE expire_snapshots(snapshot_ids = [101, 102, 103]);
-- ドライランプレビュー(メタデータの更新なし、ファイルの削除なし)
ALTER TABLE iceberg_table EXECUTE expire_snapshots(retention_period = '1d', dry_run = 1);出力:
このコマンドは、2 つのカラム (metric_name String、metric_value Int64) を持つテーブルを返します。このテーブルには、メトリクスごとに 1 行が含まれます。メトリクス名は Iceberg spec に従います。
| metric_name | 説明 |
|---|---|
deleted_data_files_count |
削除されたデータファイルの数 |
deleted_position_delete_files_count |
削除された position delete ファイルの数 |
deleted_equality_delete_files_count |
削除された equality delete ファイルの数 |
deleted_manifest_files_count |
削除されたマニフェストファイルの数 |
deleted_manifest_lists_count |
削除されたマニフェストリストファイルの数 |
deleted_statistics_files_count |
削除された統計ファイルの数 (現時点では常に 0) |
dry_run |
ドライランモードでは 1、通常実行では 0 |
このコマンドは次の手順を実行します。
- 保持ポリシー (以下を参照) を評価し、保持する必要があるスナップショットを特定します
- タイムスタンプ引数が指定されている場合は、そのタイムスタンプ以降のすべてのスナップショットも追加で保護します
- ポリシーによって保持されず、タイムスタンプによる保護も受けていないスナップショットを期限切れにします
- 期限切れになったスナップショットにのみ関連付けられているファイルを特定します
- 通常モード: 期限切れになったスナップショットを除外した新しいメタデータを生成します
- 通常モード: 到達不能になったマニフェストリスト、マニフェストファイル、データファイルを物理的に削除します
dry_run = 1モード: 手順 5 と 6 をスキップし、計算されたメトリクスのみを返します
スナップショット保持ポリシー
expire_snapshots コマンドは、Iceberg snapshot retention policy に従います。保持設定は、Iceberg テーブルのプロパティと参照ごとのオーバーライドで構成します。
| プロパティ | 範囲 | デフォルト | 説明 |
|---|---|---|---|
history.expire.min-snapshots-to-keep |
テーブル | iceberg_expire_default_min_snapshots_to_keep (デフォルト 1) |
各ブランチの祖先チェーンで保持するスナップショットの最小数 |
history.expire.max-snapshot-age-ms |
テーブル | iceberg_expire_default_max_snapshot_age_ms (デフォルト 432000000、5 日) |
ブランチで保持するスナップショットの最大保持期間 (ミリ秒) |
history.expire.max-ref-age-ms |
テーブル | iceberg_expire_default_max_ref_age_ms (デフォルト ∞) |
スナップショット参照 (ブランチまたはタグ) 自体が削除されるまでの最大経過時間 (ミリ秒) |
各スナップショット参照 (Iceberg メタデータ内の refs) では、参照ごとのフィールド min-snapshots-to-keep、max-snapshot-age-ms、max-ref-age-ms を使ってこれらの値を上書きできます。
保持の評価:
- 各ブランチ (
mainを含む) について: ブランチの先頭から祖先チェーンをたどります。次のいずれかの条件を満たす間、スナップショットは保持されます。- そのスナップショットが、チェーン内の先頭
min-snapshots-to-keep個に含まれている - そのスナップショットの経過時間が
max-snapshot-age-ms以内である (つまりnow - timestamp-ms <= max-snapshot-age-ms)
- そのスナップショットが、チェーン内の先頭
- タグについて: タグ付けされたスナップショットは、タグが
max-ref-age-msを超過しない限り保持されます。超過した場合は、タグ参照が削除されます main以外の参照で、経過時間がmax-ref-age-msを超えるものは完全に削除されます (mainブランチは削除されません)- 存在しないスナップショットを指す孤立した参照は、警告を出して削除されます
- 現在のスナップショットは常に保持されます。保持設定に関係なく保持されます
必要な権限:
ALTER TABLE EXECUTE 権限が必要です。これは ClickHouse のアクセス制御階層では ALTER TABLE の子権限です。個別に付与することも、親権限を通じて付与することもできます。
-- EXECUTE権限のみを付与する
GRANT ALTER TABLE EXECUTE ON my_iceberg_table TO my_user;
-- またはすべてのALTER TABLE権限を付与する(ALTER TABLE EXECUTEを含む)
GRANT ALTER TABLE ON my_iceberg_table TO my_user;孤立ファイルの削除
孤立ファイルとは、ストレージ上に存在するものの、Iceberg テーブルのメタデータ内にあるどのスナップショットからも参照されていないファイルのことです。これらは、書き込みの失敗、コンパクション 後の不完全なクリーンアップ、操作の中断などによって蓄積し、ストレージ使用量が際限なく増加する原因になります。remove_orphan_files コマンドは、こうした孤立ファイルを特定して削除します。
構文:
-- 位置指定形式: 名前なしの older_than 引数を1つ指定
ALTER TABLE iceberg_table EXECUTE remove_orphan_files('timestamp')
-- 名前付き形式
ALTER TABLE iceberg_table EXECUTE remove_orphan_files(
older_than = 'timestamp',
location = 'path',
dry_run = 0|1
)
-- 引数なし: すべてデフォルト値を使用 (older_than = 3日前)
ALTER TABLE iceberg_table EXECUTE remove_orphan_files()パラメータ:
| パラメータ | 型 | デフォルト | 説明 |
|---|---|---|---|
older_than |
String (timestamp) |
3日前 (iceberg_orphan_files_older_than_seconds で設定可能) |
最終更新時刻がこのタイムスタンプより古いファイルのみを、孤立ファイル候補として扱います。処理中の書き込みで作成されたファイルを削除しないための安全策です。 |
location |
String |
テーブルの格納場所 | スキャン対象を、テーブルの格納場所配下の特定のサブディレクトリ (例: 'data/' または 'metadata/') に限定します。 |
dry_run |
UInt64 |
0 |
1 の場合、孤立ファイルを特定して結果のサマリーを返しますが、実際には何も削除しません。 |
例:
-- 特定のタイムスタンプより古い孤立ファイルを削除する
ALTER TABLE iceberg_table EXECUTE remove_orphan_files('2026-03-01 00:00:00');
-- ドライラン: 削除対象のファイルをプレビューする
ALTER TABLE iceberg_table EXECUTE remove_orphan_files(dry_run = 1);
-- データディレクトリのみをスキャンする
ALTER TABLE iceberg_table EXECUTE remove_orphan_files(
older_than = '2026-03-01 00:00:00',
location = 'data/'
);
-- 位置引数の older_than と名前付き引数を組み合わせる
ALTER TABLE iceberg_table EXECUTE remove_orphan_files(
'2026-03-01 00:00:00',
dry_run = 1
);出力:
このコマンドは、カテゴリ別の削除済みファイル数 (dry_run モードでは削除対象となるファイル数) を示す metric_name と metric_value のカラムを持つテーブルを返します。ファイルカテゴリは、ファイル名の命名規則に基づくベストエフォートのヒューリスティクスで分類されます。特定のパターンに一致しないファイルは、デフォルトで deleted_data_files_count に分類されます。
| metric_name | metric_value |
|---|---|
| deleted_data_files_count | 5 |
| deleted_position_delete_files_count | 2 |
| deleted_equality_delete_files_count | 0 |
| deleted_manifest_files_count | 3 |
| deleted_manifest_lists_count | 1 |
| deleted_metadata_files_count | 0 |
| deleted_statistics_files_count | 0 |
| skipped_missing_metadata_count | 0 |
| failed_deletions_count | 0 |
設定:
| 設定 | 型 | デフォルト | 説明 |
|---|---|---|---|
allow_iceberg_remove_orphan_files |
Bool |
false |
この機能を有効にするためのゲート設定 (Experimental) 。 |
iceberg_orphan_files_older_than_seconds |
UInt64 |
259200 (3 days) |
引数を省略した場合の older_than のデフォルトしきい値 (秒単位) 。 |