メインコンテンツまでスキップ
に最終更新

Iceberg Catalog

Doris は、さまざまなメタデータサービスを介して Iceberg テーブルのデータにアクセスできます。データの読み取りに加え、INSERT、INSERT OVERWRITE、UPDATE、DELETE、MERGE INTO による Iceberg テーブルへの書き込みにも対応しています。

Apache Doris と Apache Iceberg のクイックスタート。

ヒント

Hive Catalog を使用し、Hive Metastore をメタデータサービスとして Iceberg テーブルにアクセスできます。ただし、互換性の問題を避けるため、Iceberg Catalog を直接使用することを推奨します。

適用シナリオ​

シナリオ説明
クエリの高速化Doris の分散コンピューティングエンジンから Iceberg データに直接アクセスし、クエリを高速化します。
データ統合Iceberg データを読み取って Doris の内部テーブルに書き込むか、Doris のコンピューティングエンジンを使用して ZeroETL 操作を実行します。
データの書き戻しDoris が対応する任意のデータソースのデータを処理し、Iceberg テーブルのストレージに書き戻します。

Catalog の設定​

構文​

CREATE CATALOG [IF NOT EXISTS] catalog_name PROPERTIES (
'type' = 'iceberg',
'iceberg.catalog.type' = '<iceberg_catalog_type>',
'warehouse' = '<warehouse>', --optional
{MetaStoreProperties},
{StorageProperties},
{IcebergProperties},
{CommonProperties}
);
  • <iceberg_catalog_type>

    Iceberg Catalog の種類です。次のオプションに対応します。

    • hms:Hive Metastore をメタデータサービスとして使用します。

    • rest:Iceberg Rest Catalog インターフェースと互換性のあるメタデータサービスを使用します。

    • hadoop:ファイルシステムに保存されたメタデータに直接アクセスします。

    • glue:AWS Glue をメタデータサービスとして使用します。

    • dlf:Alibaba Cloud DLF をメタデータサービスとして使用します。

    • jdbc:Iceberg JDBC Catalog をメタデータサービスとして使用します。

    • s3tables:AWS S3 Tables Catalog を使用して S3 Table Bucket にアクセスします。

  • <warehouse>

    Iceberg のウェアハウスパスです。<iceberg_catalog_type> が hadoop の場合は必須です。

    warehouse パスは Database パスの一つ上の階層を指す必要があります。たとえば、テーブルパスが s3://bucket/path/to/db1/table1 の場合、warehouse は s3://bucket/path/to/ にします。

  • {MetaStoreProperties}

    MetaStoreProperties には、Metastore メタデータサービスへの接続情報と認証情報を指定します。「[対応するメタデータサービス]」のセクションを参照してください。

  • {StorageProperties}

    StorageProperties には、ストレージシステムに関する接続情報と認証情報を指定します。「[対応するストレージシステム]」のセクションを参照してください。

  • {IcebergProperties}

    IcebergProperties には、Iceberg Catalog 固有のパラメータを指定します。

    • list-all-tables

      Hive Metastore をメタデータサービスとして使用する Iceberg Catalog 向けです。デフォルトは true です。デフォルトでは、SHOW TABLES は現在のデータベース内のすべての種類のテーブルを一覧表示します(Hive Metastore には Iceberg 以外のテーブルも保存されている場合があります)。この方法が最も高いパフォーマンスを発揮します。

      false に設定すると、Doris は各テーブルの種類を一つずつ確認し、Iceberg テーブルのみを返します。テーブル数が多い場合、このモードのパフォーマンスは低下します。

    • iceberg.rest.view-enabled

      バージョン 4.0.6 以降でサポートされています。

      Iceberg REST Catalog にのみ有効です。listViews、loadView、viewExists、dropView など、View 関連の操作を有効にするかどうかを指定します。デフォルトは true です。

      Iceberg REST Catalog の実装によっては Table API を公開していても、View API が利用できないか、エラーを返します。Doris は SHOW TABLES の実行時に ViewCatalog.listViews() を呼び出してテーブル一覧から View を除外するため、このような REST サービスでは SHOW TABLES やテーブルメタデータのデータロードが失敗する場合があります。

      その場合は、このパラメータを false に設定します。Doris は View 関連の操作をすべてスキップし、SHOW TABLES などのメタデータ操作を正常に実行できるようになります。

  • {CommonProperties}

    CommonProperties には共通プロパティを指定します。詳細は Catalog の概要 を参照してください。

メタデータキャッシュ​

外部データソースへのアクセス性能を高めるため、Apache Doris は Iceberg のメタデータをキャッシュします。対象には、データロード済みのテーブルメタデータ、パーティションデータ、マニフェスト、導出されたパーティション射影、最新スナップショット ID、推定されたファイル形式が含まれます。

ヒント

Doris 4.1.x より前のバージョンでは、メタデータキャッシュは主に FE の設定項目でグローバルに制御されます。詳細は メタデータキャッシュ を参照してください。 Doris 4.1.x 以降では、Iceberg Catalog の外部メタデータキャッシュを統一された meta.cache.* キーで設定します。以下の項目は現在のバージョンについて説明しています。Doris 4.1.x と 4.2.x では別の設定項目を使用します。これらはこのページの 4.x 版で説明しています。

キャッシュプロパティの設定​

各キャッシュエントリには、統一された形式の設定キー meta.cache.<engine>.<entry>.{enable,ttl-second,capacity,max-weight} を使用します。Iceberg の <engine> は iceberg です。meta.cache.iceberg.table.ttl-second は共有 TTL 設定で、table と partition エントリのデフォルト TTL、および独自の <entry> トークンを持たないキャッシュの TTL になります。値を 0 にするとこれらすべてが無効になり、各クエリが最新のスナップショットを直接読み取ります。

プロパティ例意味
enabletrue/falseこのキャッシュエントリを有効にするかどうか。
ttl-second600, 0, -10 はエントリを無効にします(直ちに反映され、最新データの確認に使用できます)。-1 は無期限です。その他の正の整数は、アクセス時刻を基準とした秒単位の TTL です。
capacity10000キャッシュエントリ数の上限です。0 はエントリを無効にします。
max-weight1GBDoris 4.1.4 以降でサポートされます。エントリが保持するメモリの推定量に対する任意の上限です。正の値が必要で、0 は拒否されます。以下で示すエントリにのみ指定できます。

有効条件: enable=true、ttl-second != 0、capacity > 0 の場合にエントリが有効になります。FE 全体、Catalog、またはエントリのメモリ上限も、推定メモリ使用量に基づいてキャッシュへの登録を制御します。外部メタデータキャッシュのメモリ管理 を参照してください。

キャッシュモジュール​

次のエントリには専用の設定キーがあり、max-weight を指定できます。

エントリ(<entry>)プロパティキーの接頭辞ENTRY_NAMEキャッシュする内容と効果デフォルトの有効状態 / TTL / 容量
tablemeta.cache.iceberg.table.iceberg-tableデータロード済みの Iceberg テーブルメタデータ。効果:Catalog との通信やメタデータファイルの読み取りを削減します。true / 86400 秒 / 1000
partitionmeta.cache.iceberg.partition.iceberg-partitionテーブルのスナップショットの生のパーティションデータ。true / table と同じ / 1000
manifestmeta.cache.iceberg.manifest.iceberg-manifest解析済みのマニフェスト内容。スキャン計画では enable が true の場合にのみ使用され、デフォルトは false です。キャッシュ自体は true、その使用は false / 無期限 / 100000
partition_viewmeta.cache.iceberg.partition_view.iceberg.mvcc-partition-view, iceberg.list-partitions-view一つのエントリ上限を共有する、導出された二つのパーティション射影。true / 86400 秒 / 1000

次のキャッシュには <entry> トークンがありません。Catalog と FE 全体のメモリ上限に従い、TTL は meta.cache.iceberg.table.ttl-second から取得します:iceberg-latest-snapshot(最新スナップショット ID)、iceberg-format(推定されたファイル形式)、iceberg-comment(テーブルのコメント。資格情報を払い出す REST Catalog でのみ作成)、iceberg-equality-delete-field-ids。

Iceberg テーブルのカラムスキーマは、共有の default エンジン(meta.cache.default.schema.*)によってキャッシュされます。

注記

iceberg.rest.session が user の場合、共有キャッシュがユーザーごとの認可を迂回してしまうため、table、partition、partition_view、最新スナップショット、形式のキャッシュは作成されません。資格情報を払い出す REST Catalog でも table キャッシュは作成されません。

旧パラメータと統一キーの対応・変換​

旧プロパティキー統一キー説明
schema.cache.ttl-secondmeta.cache.default.schema.ttl-secondテーブルスキーマキャッシュの有効期限

ベストプラクティス​

  • 最新データへのリアルタイムアクセス:各クエリで Iceberg テーブルの最新スナップショットを参照したい場合は、meta.cache.iceberg.table.ttl-second を 0 に設定します。
    -- Disable the table, partition, latest-snapshot, and format caches to read the latest snapshot live
    ALTER CATALOG iceberg_ctl SET PROPERTIES ("meta.cache.iceberg.table.ttl-second" = "0");
  • パフォーマンス最適化:
    • マニフェストキャッシュを有効にすると、大きなテーブルのクエリ計画を大幅に高速化できます。マニフェストが大きい場合は max-weight でメモリ使用量を制限します。
      ALTER CATALOG iceberg_ctl SET PROPERTIES (
      "meta.cache.iceberg.manifest.enable" = "true",
      "meta.cache.iceberg.manifest.max-weight" = "1GB"
      );
    • Catalog プロパティの変更に成功すると、影響を受けるメタデータキャッシュが破棄され、次回アクセス時に新しい設定で再構築されます。meta.cache.max-weight または schema.cache.ttl-second を変更すると、その Catalog のすべてのキャッシュが破棄されます。meta.cache.<engine>.<entry>.* を変更すると、そのエンジンのキャッシュが破棄されます。実行中のクエリには影響しません。

観測方法​

キャッシュのメトリクスは、システムテーブル information_schema.catalog_meta_cache_statistics で確認できます。ENTRY_NAME には上の表に記載した名前が表示され、default エンジンの行は共有のテーブルスキーマキャッシュを表します。

SELECT engine_name, entry_name,
effective_enabled, ttl_second, capacity,
estimated_size, hit_rate, max_weight, estimated_weight
FROM information_schema.catalog_meta_cache_statistics
WHERE catalog_name = 'iceberg_ctl'
ORDER BY engine_name, entry_name;

このシステムテーブルの詳細は、catalog_meta_cache_statistics を参照してください。

対応する Iceberg バージョン​

Doris バージョンIceberg SDK バージョン
2.11.6.1
3.01.6.1
3.11.9.1
4.01.9.1
4.1.4 / 4.1.4.11.10.1
4.1.5+1.11.0
dev (master)1.12.0

メタデータと読み取りのエラー(4.1.5 以降)​

  • DESCRIBE、SHOW COLUMNS、SHOW CREATE TABLE は、現在の Iceberg スキーマにある必須・任意の宣言を保持します。スキャンでは、スキーマ進化によって存在しないフィールドも処理できます。表示された NOT NULL 宣言は、すべての過去のファイルにそのフィールドが存在することを保証しません。
  • dev バージョンでは、行レベルの書き込みに使うパーティションメタデータを、シリアライズされたパーティションデータとして保持します。4.1.5 のエラー Cannot produce Iceberg row IDs with unsupported partition types in spec ... は以前の Row ID 表現に関するもので、現在の表現には当てはまりません。
  • コミット済みスナップショットが参照するデータファイルまたは削除ファイルが欠けている場合、ignore_not_found_file_in_external_table=true であってもクエリは失敗します。欠けたオブジェクトを復元するか、必要なファイルがすべてそろった有効なスナップショットを選択してください。
  • schema.name-mapping.default には有効な Iceberg Name Mapping の JSON 配列が必要です。値が無効な場合、現在のカラム名にフォールバックして NULL を返すのではなく、データスキャンが失敗します。Spark などの書き込みエンジンでこのプロパティを修正または削除し、Doris でテーブルを更新してください。メタデータのシステムテーブルへのクエリでは、このデータスキャン時の検証は行われません。

対応する Iceberg 形式​

  • Iceberg V1/V2 形式に対応します。
  • Position Delete と Equality Delete の読み取りに対応します。
  • Deletion Vector の読み取りに対応します(4.1.0 以降)。

対応するメタデータサービス​

注:Doris のバージョンによって、対応するサービスの種類やパラメータは若干異なります。「[例]」のセクションを参照してください。

Iceberg Catalog の機能対応表​

メタデータサービステーブルクエリView クエリDDL 操作データの書き戻しシステムテーブル(3.1+ 以降でサポート)
Hive MetaStore✅✅✅✅✅
AWS Glue✅✅❌❌✅
Aliyun DLF✅✅❌❌❌
Iceberg Rest Catalog✅✅サービスプロバイダーによるサービスプロバイダーによるサービスプロバイダーによる
FileSystem✅✅✅✅✅

labels システムテーブルはバージョン 5.0.0 以降でサポートされ、Iceberg REST Catalog でのみ利用できます。後述の labels を参照してください。

対応するストレージシステム​

注:Doris のバージョンによって、対応するサービスの種類やパラメータは若干異なります。「[例]」のセクションを参照してください。

対応するデータ形式​

バージョン 4.1.4 以降では、ファイル形式をデータファイル(split)ごとに判定します。そのため、Parquet と ORC の両方のデータファイルを含む単一の Iceberg テーブルも正常にクエリできます。

バージョン 4.1.4 以降では、Iceberg の identity パーティションメタデータが各 split とともに渡され、パスのパーティションキーはテーブル内のすべてのパーティション仕様の identity カラムを網羅します。その結果、Partition Evolution を経たテーブルでも、パーティションカラムの値が正しく返されます。

カラム型のマッピング​

Doris 4.2 の完全なマッピング表、精度の規則、非対応の型については、Iceberg から Doris へのデータ型マッピング を参照してください。

カラム名の大文字と小文字​

Doris は Iceberg テーブルのカラム名の元の大文字・小文字を保持し、読み取り時には大文字・小文字を区別せずにカラムを照合します。大文字や大文字・小文字が混在するカラム名(例:UserId、ORDER_ID)も正常にクエリできます。

バージョンに関する注記

4.0 系の 4.0.8 より前のバージョンでは、読み取り時に完全一致でカラムを特定していたため、大文字・小文字が混在するカラム名を持つ Iceberg テーブルや Paimon テーブルで、誤ったカラムを読み取ったり、クエリが失敗したりする場合がありました。この問題は 4.0.8 で修正されました。

Namespace のマッピング​

Iceberg のメタデータ階層は Catalog -> Namespace -> Table です。Namespace は複数の階層を持つことができます(Nested Namespace)。

      ┌─────────┐
│ Catalog │
└────┬────┘
│
┌─────┴─────┐
┌──▼──┐ ┌──▼──┐
│ NS1 │ │ NS2 │
└──┬──┘ └──┬──┘
│ │
┌────▼───┐ ┌──▼──┐
│ Table1 │ │ NS3 │
└────────┘ └──┬──┘
│
┌──────┴───────┐
┌────▼───┐ ┌────▼───┐
│ Table2 │ │ Table3 │
└────────┘ └────────┘

バージョン 3.1.2 以降、Iceberg Rest Catalog については、Doris は Nested Namespace のマッピングに対応しています。

上の例では、テーブルは次の規則に従って Doris のメタデータにマッピングされます。

Catalogデータベーステーブル
CatalogNS1Table1
CatalogNS2.NS3Table2
CatalogNS2.NS3Table3

Nested Namespace のサポートは明示的に有効にする必要があります。詳細は Iceberg Rest Catalog を参照してください。

例​

Hive Metastore​

バージョン 3.1+

Kerberos 認証なしで HMS と HDFS のサービスにアクセスする

CREATE CATALOG iceberg_hms_on_hdfs_catalog PROPERTIES (
'type' = 'iceberg',
'iceberg.catalog.type' = 'hms',
'warehouse' = 'hdfs://127.0.0.1:8320/user/iceberg/warehouse/iceberg-hms-hdfs-warehouse',
'hive.metastore.uris' = 'thrift://127.0.0.1:9383',
'fs.defaultFS' = 'hdfs://127.0.0.1:8320',
'hadoop.username' = 'doris'
);

Kerberos 認証を有効にして HMS と HDFS のサービスにアクセスする

CREATE CATALOG iceberg_hms_on_hdfs_kerberos_hdfs_catalog PROPERTIES (
'type' = 'iceberg',
'iceberg.catalog.type' = 'hms',
'warehouse' = 'hdfs://127.0.0.1:8520/iceberg-hms-hdfs-warehouse',
'hive.metastore.uris' = 'thrift://127.0.0.1:9583',
'hive.metastore.client.principal' = 'hive/presto-master.docker.cluster@LABS.TERADATA.COM',
'hive.metastore.client.keytab' = '/keytabs/hive-presto-master.keytab',
'hive.metastore.service.principal' = 'hive/hadoop-master@LABS.TERADATA.COM',
'hive.metastore.sasl.enabled' = 'true',
'hive.metastore.authentication.type' = 'kerberos',
'hadoop.security.auth_to_local' = 'RULE:[2:\$1@\$0](.*@LABS.TERADATA.COM)s/@.*//
RULE:[2:\$1@\$0](.*@OTHERLABS.TERADATA.COM)s/@.*//
RULE:[2:\$1@\$0](.*@OTHERREALM.COM)s/@.*//
DEFAULT',
'fs.defaultFS' = 'hdfs://127.0.0.1:8520',
'hadoop.security.authentication' = 'kerberos',
'hadoop.kerberos.principal'='hive/presto-master.docker.cluster@LABS.TERADATA.COM',
'hadoop.kerberos.keytab' = '/keytabs/hive-presto-master.keytab'
);
バージョン 2.1 & 3.0

Kerberos 認証なしで HMS と HDFS のサービスにアクセスする

CREATE CATALOG iceberg_hms_on_hdfs_catalog PROPERTIES (
'type' = 'iceberg',
'iceberg.catalog.type' = 'hms',
'hive.metastore.uris' = 'thrift://127.0.0.1:9383',
'warehouse' = 'hdfs://127.0.0.1:8320/user/iceberg/warehouse/iceberg-hms-hdfs-warehouse',
'hadoop.username' = 'doris',
'fs.defaultFS' = 'hdfs://127.0.0.1:8320'
);

Kerberos 認証を有効にして HMS と HDFS のサービスにアクセスする

CREATE CATALOG iceberg_hms_on_hdfs_kerberos_hdfs_catalog PROPERTIES (
'type' = 'iceberg',
'iceberg.catalog.type' = 'hms',
'warehouse' = 'hdfs://127.0.0.1:8520/iceberg-hms-hdfs-warehouse',
'hive.metastore.uris' = 'thrift://127.0.0.1:9583',
'hive.metastore.kerberos.principal' = 'hive/hadoop-master@LABS.TERADATA.COM',
'hive.metastore.sasl.enabled' = 'true',
'hive.metastore.authentication.type' = 'kerberos',
'hadoop.security.auth_to_local' = 'RULE:[2:\$1@\$0](.*@LABS.TERADATA.COM)s/@.*//
RULE:[2:\$1@\$0](.*@OTHERLABS.TERADATA.COM)s/@.*//
RULE:[2:\$1@\$0](.*@OTHERREALM.COM)s/@.*//
DEFAULT',
'fs.defaultFS' = 'hdfs://127.0.0.1:8520',
'hadoop.security.authentication' = 'kerberos',
'hadoop.kerberos.principal'='hive/presto-master.docker.cluster@LABS.TERADATA.COM',
'hadoop.kerberos.keytab' = '/keytabs/hive-presto-master.keytab'
);

AWS Glue​

バージョン 3.1+

AWS Glue と S3 ストレージサービスは同じ認証資格情報を共有します。

CREATE CATALOG `iceberg_glue_on_s3_catalog_` PROPERTIES (
'type' = 'iceberg',
'iceberg.catalog.type' = 'glue',
'warehouse' = 's3://bucket/iceberg-glue-s3-warehouse',
'glue.region' = 'ap-northeast-1',
'glue.endpoint' = 'https://glue.ap-northeast-1.amazonaws.com',
'glue.access_key' = '<ak>',
'glue.secret_key' = '<sk>'
);

Glue サービスと S3 の認証資格情報が異なる場合は、次の方法で S3 の認証資格情報を個別に指定できます。

CREATE CATALOG `iceberg_glue_on_s3_catalog_` PROPERTIES (
'type' = 'iceberg',
'iceberg.catalog.type' = 'glue',
'warehouse' = 's3://selectdb-qa-datalake-test/iceberg-glue-s3-warehouse',
'glue.region' = 'ap-northeast-1',
'glue.endpoint' = 'https://glue.ap-northeast-1.amazonaws.com',
'glue.access_key' = '<ak>',
'glue.secret_key' = '<sk>',
's3.endpoint' = 'https://s3.ap-northeast-1.amazonaws.com',
's3.region' = 'ap-northeast-1',
's3.access_key' = '<ak>',
's3.secret_key' = '<sk>'
);
CREATE CATALOG `glue_iceberg_iamrole` PROPERTIES (
'type' = 'iceberg',
'iceberg.catalog.type' = 'glue',
'warehouse' = 's3://bucket/warehouse',
'glue.region' = 'us-east-1',
'glue.endpoint' = 'https://glue.us-east-1.amazonaws.com',
'glue.role_arn' = '<role_arn>'
);
バージョン 2.1 & 3.0

AWS Glue と S3 ストレージサービスは同じ認証資格情報を共有します。

EC2 以外の環境では、aws configure を使用して Credentials 情報を設定し、~/.aws ディレクトリに資格情報ファイルを生成する必要があります。

CREATE CATALOG glue PROPERTIES (
'type'='iceberg',
'iceberg.catalog.type' = 'glue',
'glue.endpoint' = 'https://glue.us-east-1.amazonaws.com',
'glue.access_key' = '<ak>',
'glue.secret_key' = '<sk>'
);

Aliyun DLF​

バージョン 4.1+
CREATE CATALOG iceberg_dlf2_catalog PROPERTIES (
'type' = 'iceberg',
'iceberg.catalog.type' = 'rest',
'iceberg.rest.uri' = 'http://<region>-vpc.dlf.aliyuncs.com/iceberg',
'warehouse' = '<your-catalog-name>',
'iceberg.rest.sigv4-enabled' = 'true',
'iceberg.rest.signing-name' = 'DlfNext',
'iceberg.rest.access-key-id' = '<ak>',
'iceberg.rest.secret-access-key' = '<sk>',
'iceberg.rest.signing-region' = '<region>',
'iceberg.rest.vended-credentials-enabled' = 'true',
'io-impl' = 'org.apache.iceberg.rest.DlfFileIO',
'fs.oss.support' = 'true'
);
バージョン 3.1+
CREATE CATALOG iceberg_dlf_catalog_catalog PROPERTIES (
'type' = 'iceberg',
'iceberg.catalog.type' = 'dlf',
'warehouse' = 'oss://bucket/iceberg-dlf-oss-warehouse',
'dlf.uid' = '203225413946383283',
'dlf.catalog_id' = 'p2_regression_case',
'dlf.region' = 'cn-beijing',
'dlf.endpoint' = 'datalake.cn-beijing.aliyuncs.com',
'dlf.access_key' = '<ak>',
'dlf.secret_key' = '<sk>'
);
バージョン 2.1 & 3.0
CREATE CATALOG iceberg_dlf_catalog_catalog PROPERTIES (
'type' = 'iceberg',
'iceberg.catalog.type' = 'dlf',
'warehouse' = 'oss://bucket/iceberg-dlf-oss-warehouse',
'dlf.uid' = '203225413946383283',
'dlf.catalog.id' = 'catalog_id',
'dlf.region' = 'cn-beijing',
'dlf.access_key' = '<ak>',
'dlf.secret_key' = '<sk>'
);

Iceberg Rest Catalog​

動作変更(4.1.4)

バージョン 4.1.4 以降、iceberg.rest.signing-name に glue、s3tables、osstables などのマネージド署名サービスを設定する場合は、'iceberg.rest.sigv4-enabled' = 'true' も必ず設定する必要があります。設定しないと、Catalog の作成が次のエラーで失敗します。

Rest Catalog requires sigv4-enabled set to true when signing-name is <name>

既存の Catalog で sigv4-enabled を有効にせず signing-name だけを設定していた場合、アップグレード後に検証が失敗するため、このプロパティを追加する必要があります。

osstables を使用する場合は、iceberg.rest.signing-region と iceberg.rest.sigv4-enabled = 'true' の両方が必要です。設定しないと、次のエラーが報告されます。

Rest Catalog requires signing-region and sigv4-enabled set to true when signing-name is osstables
バージョン 3.1+
CREATE CATALOG iceberg_static_s3 PROPERTIES (
'type' = 'iceberg',
'warehouse' = 's3://warehouse',
'iceberg.catalog.type' = 'rest',
'iceberg.rest.uri' = 'http://127.0.0.1:8181',
's3.endpoint' = 'https://s3.ap-east-1.amazonaws.com',
's3.access_key' = '<ak>',
's3.secret_key' = '<sk>',
's3.region' = 'ap-east-1'
);
バージョン 2.1 & 3.0
CREATE CATALOG iceberg_static_s3 PROPERTIES (
'type' = 'iceberg',
'warehouse' = 's3://warehouse',
'iceberg.catalog.type' = 'rest',
'uri' = 'http://127.0.0.1:8181',
's3.endpoint' = 'https://s3.ap-east-1.amazonaws.com',
's3.access_key' = '<ak>',
's3.secret_key' = '<sk>',
's3.region' = 'ap-east-1'
);

Iceberg JDBC Catalog​

注

これは実験的な機能で、バージョン 4.1.0 以降でサポートされています。

バージョン 4.1+

PostgreSQL をメタデータストレージとして使用し、S3 と組み合わせる

CREATE CATALOG iceberg_jdbc_postgresql PROPERTIES (
'type' = 'iceberg',
'iceberg.catalog.type' = 'jdbc',
'iceberg.jdbc.catalog_name' = 'iceberg_jdbc_postgresql',
'iceberg.jdbc.uri' = 'jdbc:postgresql://127.0.0.1:5432/iceberg_db',
'iceberg.jdbc.user' = 'iceberg_user',
'iceberg.jdbc.password' = 'password',
'iceberg.jdbc.init-catalog-tables' = 'true',
'iceberg.jdbc.schema-version' = 'V1',
'iceberg.jdbc.driver_class' = 'org.postgresql.Driver',
'iceberg.jdbc.driver_url' = '<jdbc_driver_jar>',
'warehouse' = 's3://bucket/warehouse',
's3.access_key' = '<ak>',
's3.secret_key' = '<sk>',
's3.endpoint' = 'https://s3.us-east-1.amazonaws.com',
's3.region' = 'us-east-1'
);

FileSystem​

バージョン 3.1+

Kerberos 認証なしで HDFS サービスにアクセスする

CREATE CATALOG iceberg_fs_on_hdfs_catalog PROPERTIES (
'type' = 'iceberg',
'iceberg.catalog.type' = 'hadoop',
'warehouse' = 'hdfs://127.0.0.1:8320/user/iceberg/warehouse/iceberg-fs-hdfs-warehouse',
'hadoop.username' = 'doris',
'fs.defaultFS' = 'hdfs://127.0.0.1:8320'
);

Kerberos 認証を有効にして HDFS サービスにアクセスする

CREATE CATALOG iceberg_fs_on_hdfs_kerberos_catalog PROPERTIES (
'type' = 'iceberg',
'iceberg.catalog.type' = 'hadoop',
'warehouse' = 'hdfs://127.0.0.1:8520/iceberg-fs-hdfs-warehouse',
'fs.defaultFS' = 'hdfs://127.0.0.1:8520',
'hadoop.security.authentication' = 'kerberos',
'hadoop.kerberos.principal' = 'hive/presto-master.docker.cluster@LABS.TERADATA.COM',
'hadoop.kerberos.keytab' = '/keytabs/hive-presto-master.keytab'
);

バージョン 2.1 & 3.0

Kerberos 認証なしで HDFS サービスにアクセスする

CREATE CATALOG iceberg_fs_on_hdfs_catalog PROPERTIES (
'type' = 'iceberg',
'iceberg.catalog.type' = 'hadoop',
'warehouse' = 'hdfs://127.0.0.1:8320/user/iceberg/warehouse/iceberg-fs-hdfs-warehouse',
'hadoop.username' = 'doris',
'fs.defaultFS' = 'hdfs://127.0.0.1:8320'
);

Kerberos 認証を有効にして HDFS サービスにアクセスする

CREATE CATALOG iceberg_fs_on_hdfs_kerberos_catalog PROPERTIES (
'type' = 'iceberg',
'iceberg.catalog.type' = 'hadoop',
'warehouse' = 'hdfs://127.0.0.1:8520/iceberg-fs-hdfs-warehouse',
'fs.defaultFS' = 'hdfs://127.0.0.1:8520',
'hadoop.security.authentication' = 'kerberos',
'hadoop.kerberos.principal'='hive/presto-master.docker.cluster@LABS.TERADATA.COM',
'hadoop.kerberos.keytab' = '/keytabs/hive-presto-master.keytab'
);

AWS S3 Tables​

バージョン 3.1+

S3 Tables との統合 のドキュメントを参照してください。

CREATE CATALOG aws_s3_tables PROPERTIES (
'type' = 'iceberg',
'iceberg.catalog.type' = 'rest',
'warehouse' = 'arn:aws:s3tables:us-east-1:<account_id>:bucket/<s3_table_bucket_name>',
'iceberg.rest.uri' = 'https://s3tables.us-east-1.amazonaws.com/iceberg',
'iceberg.rest.sigv4-enabled' = 'true',
'iceberg.rest.signing-name' = 's3tables',
'iceberg.rest.signing-region' = 'us-east-1',
'iceberg.rest.access-key-id' = '<ak>',
'iceberg.rest.secret-access-key' = '<sk>'
);
バージョン 3.0.6+

S3 Tables との統合 のドキュメントを参照してください。

CREATE CATALOG test_s3tables_catalog PROPERTIES (
'type' = 'iceberg',
'iceberg.catalog.type' = 's3tables',
'warehouse' = 'arn:aws:s3tables:ap-east-1:9527:bucket/doris-s3-table-bucket',
's3.region' = 'ap-east-1',
's3.endpoint' = 'https://s3.ap-east-1.amazonaws.com',
's3.access_key' = '<ak>',
's3.secret_key' = '<sk>'
);

Alibaba Cloud OSS Tables​

バージョン 4.1.4+

設定と使用方法の詳細は、Alibaba Cloud OSS Tables との統合 を参照してください。

CREATE CATALOG oss_tables PROPERTIES (
'type' = 'iceberg',
'iceberg.catalog.type' = 'rest',
'iceberg.rest.uri' = 'https://<region>.oss-tables.aliyuncs.com/iceberg',
'warehouse' = 'acs:osstables:<region>:<account_id>:bucket/<table_bucket_name>',
'iceberg.rest.sigv4-enabled' = 'true',
'iceberg.rest.signing-name' = 'osstables',
'iceberg.rest.signing-region' = '<region>',
'iceberg.rest.view-enabled' = 'false',
'io-impl' = 'org.apache.iceberg.aws.s3.S3FileIO',
'oss.endpoint' = 'https://oss-<region>.aliyuncs.com',
'oss.region' = '<region>',
'oss.access_key' = '<access_key_id>',
'oss.secret_key' = '<access_key_secret>',
'oss.use_path_style' = 'false',
'test_connection' = 'true'
);

クエリ操作​

基本クエリ​

-- 1. switch to catalog, use database and query
SWITCH iceberg;
USE iceberg_db;
SELECT * FROM iceberg_tbl LIMIT 10;

-- 2. use iceberg database directly
USE iceberg.iceberg_db;
SELECT * FROM iceberg_tbl LIMIT 10;

-- 3. use full qualified name to query
SELECT * FROM iceberg.iceberg_db.iceberg_tbl LIMIT 10;

ファイルメタデータカラム​

バージョン 4.2.0 以降でサポートされています。

Doris は Iceberg データテーブルに対し、二つの隠しメタデータカラムを公開します。各クエリ結果を生成した物理データファイルと行を特定するために使用できます。

カラム型説明
_fileSTRING NOT NULLIceberg データファイルについて記録された元のパス。
_posBIGINT NOT NULLデータファイル全体における、0 から始まる物理的な行位置。

前提条件:前述の例に従って Iceberg Catalog を設定し、id カラムを含み、Parquet または ORC ファイルを使用する Iceberg データテーブルを作成します。次のクエリは、iceberg_tbl に id の値が 1 と 2 の行がすでに存在することを前提とします。

SELECT id, `_file`, `_pos`
FROM iceberg.iceberg_db.iceberg_tbl
ORDER BY `_file`, `_pos`;

結果の例(ファイルパスはテーブルの場所によって異なります):

+----+---------------------------------------+------+
| id | _file | _pos |
+----+---------------------------------------+------+
| 1 | s3://bucket/warehouse/db/table/a.orc | 0 |
| 2 | s3://bucket/warehouse/db/table/a.orc | 1 |
+----+---------------------------------------+------+

デフォルトでは、これらのカラムは SELECT * や DESC に表示されません。

SELECT * と DESC に隠しカラムを含めるには、セッションで show_hidden_columns を有効にします。

SET show_hidden_columns = true;

関連するセッション変数:

変数型デフォルト必須効果
show_hidden_columnsBOOLEANfalseいいえSELECT * と DESC に隠しカラムを含めます。カラムを明示的に参照する場合は不要です。
enable_file_scanner_v2BOOLEANtrueいいえクエリでこれらのメタデータカラムを参照する場合は、有効のままにする必要があります。
force_jni_scannerBOOLEANfalseいいえJNI リーダーはこれらのメタデータカラムを生成できないため、無効のままにする必要があります。

行位置は物理ファイル全体を基準にします。述語によるフィルタリング、削除処理、スキャンの分割によって、残った行に新しい番号が付けられることはありません。したがって、_file と _pos の組み合わせで、現在のテーブルスナップショット内の物理レコードを特定できます。データファイルの再書き込みやコンパクションによって両方の値が変わる可能性があるため、安定した論理行 ID として使用しないでください。

注意

これらのカラムを使用できるのは、Iceberg データテーブルを FileScannerV2 のネイティブ Parquet または ORC リーダーで読み取る場合だけです。enable_file_scanner_v2 が無効、force_jni_scanner が有効、または選択されたデータファイルにネイティブ Parquet/ORC リーダーを使用できない場合、これらのカラムを参照するクエリは失敗します。

_file と _pos は予約名で、大文字・小文字を区別せずに比較されます。Iceberg テーブルの物理カラム名に使用しないでください。

タイムトラベル​

Iceberg テーブルの特定のスナップショットを読み取れます。

デフォルトでは、読み取りリクエストは最新のスナップショットバージョンにアクセスします。

Iceberg テーブルのスナップショットは、$snapshots システムテーブルでクエリできます。

動作変更(4.1.4)

バージョン 4.1.4 以降、iceberg_meta() テーブル関数は削除されました。代わりに Iceberg システムテーブル(例:iceberg_tbl$snapshots)を使用してメタデータをクエリしてください。後述の「システムテーブル」を参照してください。

SELECT * FROM iceberg_ctl.iceberg_db.iceberg_tbl$snapshots\G

*************************** 1. row ***************************
committed_at: 2024-11-28 11:07:29
snapshot_id: 8903826400153112036
parent_id: -1
operation: append
manifest_list: oss://path/to/metadata/snap-8903826400153112036-1-3835e66d-9a18-4cb0-b9b0-9ec80527ad8d.avro
summary: {"added-data-files":"2","added-records":"3","added-files-size":"2742","changed-partition-count":"2","total-records":"3","total-files-size":"2742","total-data-files":"2","total-delete-files":"0","total-position-deletes":"0","total-equality-deletes":"0"}
*************************** 2. row ***************************
committed_at: 2024-11-28 11:10:11
snapshot_id: 6099853805930794326
parent_id: 8903826400153112036
operation: append
manifest_list: oss://path/to/metadata/snap-6099853805930794326-1-dd46a1bd-219b-4fb0-bb46-ac441d8b3105.avro
summary: {"added-data-files":"1","added-records":"1","added-files-size":"1367","changed-partition-count":"1","total-records":"4","total-files-size":"4109","total-data-files":"3","total-delete-files":"0","total-position-deletes":"0","total-equality-deletes":"0"}

FOR TIME AS OF と FOR VERSION AS OF の句を使用すると、スナップショット ID またはスナップショットの作成時刻に基づいて過去のデータを読み取れます。例を示します。

-- Read data as of a specific timestamp
SELECT * FROM iceberg_table FOR TIME AS OF '2023-01-01 00:00:00';

-- Read data as of a specific snapshot ID
SELECT * FROM iceberg_table FOR VERSION AS OF 123456789;

4.1.5 以降、FOR TIME AS OF は yyyy-MM-dd HH:mm:ss の後に 1~9 桁の小数秒を受け付けます。この値をセッションのタイムゾーンで解釈し、スナップショット選択のためにミリ秒へ変換します。たとえば FOR TIME AS OF '2024-01-01 12:00:00.123456' を使用できます。スナップショット選択の精度はミリ秒であり、この構文を受け付けてもスナップショット時刻のナノ秒精度は保持されません。

Doris 4.1.5 では、カラム名の変更、削除、型の昇格、パーティション進化後の過去のスナップショット読み取りも修正されました。各ファイルは、現在のパーティション仕様だけでなく、そのファイルの書き込み時に有効だった仕様に従って解釈されます。履歴クエリを現在のマテリアライズドビューから読み取るように書き換えてはいけません。

ブランチとタグ​

3.1.0 以降。

ブランチとタグの作成、削除、管理については「[ブランチとタグの管理]」を参照してください。

Iceberg テーブルの特定のブランチとタグの読み取りに対応しています。

Spark や Trino などのシステムとの互換性のため、複数の構文を使用できます。

-- BRANCH
SELECT * FROM iceberg_tbl@branch(branch1);
SELECT * FROM iceberg_tbl@branch("name" = "branch1");
SELECT * FROM iceberg_tbl FOR VERSION AS OF 'branch1';

-- TAG
SELECT * FROM iceberg_tbl@tag(tag1);
SELECT * FROM iceberg_tbl@tag("name" = "tag1");
SELECT * FROM iceberg_tbl FOR VERSION AS OF 'tag1';

FOR VERSION AS OF 構文では、Doris がパラメータをタイムスタンプまたはブランチ/タグ名として自動的に判別します。

View​

3.1.0 以降

Iceberg View のクエリに対応しています。View のクエリ方法は通常のテーブルクエリと同じです。次の点に注意してください。

  • hms タイプの Iceberg Catalog のみサポートします。
  • View 定義の SQL は Doris の SQL 方言と互換性が必要です。互換性がない場合は解析エラーが発生します(方言変換機能は将来のバージョンで提供予定です)。

Iceberg V3 の隠しカラム(Row Lineage)​

ヒント

これは実験的な機能で、バージョン 4.1.0 以降でサポートされています。

Doris は Iceberg V3 テーブルの Row Lineage 隠しカラムをクエリできます。Iceberg V3 では、データ変更レコードの追跡に使用する Row Lineage データを含むシステムの隠しカラムが導入されました。増分同期やデータ監査に適しています。

  • _row_id:データ行を一意に識別する数値です(データが書き込まれたファイルと位置に基づいて生成されます)。
  • _last_updated_sequence_number:その行が最後に変更されたときの Sequence Number です。UPDATE または MERGE INTO 操作でデータを更新すると、この値はバージョン番号とともに自動的に増加します。

隠しカラムのクエリ方法:

デフォルトでは、DESC や SELECT * を使用しても隠しカラムは表示されません。カラム名を直接指定して明示的にクエリできます。

SELECT id, _row_id, _last_updated_sequence_number FROM iceberg_tbl;

セッション変数 show_hidden_columns を有効にすると、DESC や SELECT * などの通常の表示にも隠しカラムを含められます。

SET show_hidden_columns = true;
DESC iceberg_tbl;

注意事項:

  1. これらの行レベルのパラメータを生成するには、Iceberg テーブルの形式バージョン(format-version)を 3 に設定する必要があります。V1 および V2 形式のテーブルで Row Lineage カラムをクエリすると、エラーが発生する場合があります。
  2. 隠しカラムはシステムが管理します。INSERT などの書き込みステートメントで、ユーザーが _row_id または _last_updated_sequence_number を明示的に指定したり、書き込んだりすることはできません。バージョン 4.1.4 以降、format-version >= 3 のテーブルへの INSERT ステートメントのカラム一覧に Row Lineage カラムを指定すると、直ちに Cannot specify invisible column '<name>' in INSERT statement というエラーになります。

Iceberg V3 のデフォルト値​

バージョン 4.1.4 以降でサポートされています。

Iceberg V3 は二種類のカラムのデフォルト値を定義しており、Doris は両方に対応します。

  • initial-default:カラム追加時に既存の過去のデータに割り当てるデフォルト値です。カラムが存在する前に書き込まれた古いデータファイルを読み取る場合、Doris は NULL の代わりにこのデフォルト値を返します。Parquet と ORC の両方に対応し、トップレベルのカラム、STRUCT 内のネストしたサブフィールド、全体が存在しない複合型の親カラムに適用されます。述語の評価時にも有効です。
  • write-default:書き込み時に指定されなかったカラムに設定されるデフォルト値です。INSERT INTO t (subset of columns) VALUES (...) では、一覧にないカラムに現在の write-default が書き込まれます(以前のバージョンでは NULL が書き込まれました)。

DDL でデフォルト値を指定する:

ALTER TABLE iceberg_tbl ADD COLUMN c1 INT DEFAULT 10;

このステートメントは Iceberg の write-default と initial-default の両方を設定します。テーブルの format-version が 3 である必要があります。V1 と V2 のテーブルは、NULL 以外のデフォルト値を持つカラムに対応していません。

DEFAULT() 式:

バージョン 4.1.4 以降では、DML でカラムのデフォルト値を明示的に参照する DEFAULT(<column>) 式を使用できます。INSERT、UPDATE ... SET、MERGE INTO の各分岐で使用できます。

INSERT INTO iceberg_tbl VALUES (1, DEFAULT(c1));

UPDATE iceberg_tbl SET c1 = DEFAULT(c1) WHERE id = 1;

MERGE INTO iceberg_tbl t USING src s ON t.id = s.id
WHEN NOT MATCHED THEN INSERT VALUES (s.id, DEFAULT(c1));

動作:

  • Iceberg の書き込み先テーブルでは、DEFAULT() はその書き込みに固定された Iceberg スキーマに対して解決されます。書き込み先に含まれないカラムを参照すると、DEFAULT requires a target column reference または Cannot find column information for DEFAULT(<col>) が報告されます。
  • Iceberg 以外のカラムには、そのカラムのデフォルト値が使用されます。デフォルト値がなく、カラムが NOT NULL または自動増分の場合、Column '<name>' has no default value and does not allow NULL or column is auto-increment というエラーになります。NULL を許容するカラムにデフォルト値がない場合は NULL が使用されます。
  • その他のエラーには、DEFAULT requires a column reference, but got: <expr> と DEFAULT cannot be used on generated column '<name>' があります。
注

Iceberg の write-default は書き込み側のコネクターの概念です。DESCRIBE、SHOW CREATE TABLE、information_schema.columns.COLUMN_DEFAULT には表示されません。

システムテーブル​

3.1.0 以降

Doris は Iceberg システムテーブルのクエリに対応しており、テーブルに関するメタデータ情報を取得できます。システムテーブルを使用して、スナップショット履歴、マニフェストファイル、データファイル、パーティションなどのメタデータを確認できます。

Iceberg テーブルのメタデータにアクセスするには、テーブル名の後に $ とシステムテーブル名を付けます。

SELECT * FROM iceberg_table$system_table_name;

たとえば、テーブルの履歴を確認するには、次を実行します。

SELECT * FROM iceberg_table$history;

all_manifests システムテーブルはバージョン 4.0.4 以降でサポートされています。

position_deletes システムテーブルはバージョン 4.1.4 以降でサポートされています。

labels システムテーブルはバージョン 5.0.0 以降でサポートされ、Iceberg REST Catalog でのみ利用できます。

動作変更(4.1.4)

バージョン 4.1.4 以降、Iceberg システムテーブルのクエリにはネイティブの実行経路が使用され、iceberg_meta() テーブル関数は削除されました。代わりに <table>$<system_table_name> というシステムテーブル構文を使用してください。ICEBERG_META を参照してください。

システムテーブル自体のアクセス構文と返される結果は変わりません。また、システムテーブルで SHOW CREATE TABLE がサポートされるようになりました。

entries​

テーブルの現在のスナップショットに含まれるすべてのマニフェストエントリを表示します。

all_entries と entries は似ていますが、all_entries はすべてのスナップショットのエントリを含み、entries は現在のスナップショットのエントリのみを含みます。

SELECT * FROM iceberg_table$entries;

結果:

+--------+---------------------+-----------------+----------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| status | snapshot_id | sequence_number | file_sequence_number | data_file | readable_metrics |
+--------+---------------------+-----------------+----------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| 2 | 4890031351138056789 | 1 | 1 | {"content":0, "file_path":"s3://.../iceberg_table/data/id=1/00000-16-79ef2fd7-9997-47eb-a91a-9f7af8201315-0-00001.parquet", "file_format":"PARQUET", "spec_id":0, "partition":{"id":1}, "record_count":1, "file_size_in_bytes":625, "column_sizes":{1:36, 2:41}, "value_counts":{1:1, 2:1}, "null_value_counts":{1:0, 2:0}, "nan_value_counts":{}, "lower_bounds":{1:" ", 2:"Alice"}, "upper_bounds":{1:" ", 2:"Alice"}, "key_metadata":null, "split_offsets":[4], "equality_ids":null, "sort_order_id":0, "first_row_id":null, "referenced_data_file":null, "content_offset":null, "content_size_in_bytes":null} | {"id":{"column_size":36, "value_count":1, "null_value_count":0, "nan_value_count":null, "lower_bound":1, "upper_bound":1}, "name":{"column_size":41, "value_count":1, "null_value_count":0, "nan_value_count":null, "lower_bound":"Alice", "upper_bound":"Alice"}} |
| 0 | 1851184769713369003 | 1 | 1 | {"content":0, "file_path":"s3://.../iceberg_table/data/id=2/00000-16-79ef2fd7-9997-47eb-a91a-9f7af8201315-0-00002.parquet", "file_format":"PARQUET", "spec_id":0, "partition":{"id":2}, "record_count":1, "file_size_in_bytes":611, "column_sizes":{1:36, 2:39}, "value_counts":{1:1, 2:1}, "null_value_counts":{1:0, 2:0}, "nan_value_counts":{}, "lower_bounds":{1:" ", 2:"Bob"}, "upper_bounds":{1:" ", 2:"Bob"}, "key_metadata":null, "split_offsets":[4], "equality_ids":null, "sort_order_id":0, "first_row_id":null, "referenced_data_file":null, "content_offset":null, "content_size_in_bytes":null} | {"id":{"column_size":36, "value_count":1, "null_value_count":0, "nan_value_count":null, "lower_bound":2, "upper_bound":2}, "name":{"column_size":39, "value_count":1, "null_value_count":0, "nan_value_count":null, "lower_bound":"Bob", "upper_bound":"Bob"}} |
+--------+---------------------+-----------------+----------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+

files​

テーブルの現在のスナップショットのファイル一覧を表示します。

SELECT * FROM iceberg_table$files;

結果:

+---------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------------+---------+-----------+--------------+--------------------+--------------+--------------+-------------------+------------------+-----------------------+-----------------------+--------------+---------------+--------------+---------------+--------------+----------------------+----------------+-----------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| content | file_path | file_format | spec_id | partition | record_count | file_size_in_bytes | column_sizes | value_counts | null_value_counts | nan_value_counts | lower_bounds | upper_bounds | key_metadata | split_offsets | equality_ids | sort_order_id | first_row_id | referenced_data_file | content_offset | content_size_in_bytes | readable_metrics |
+---------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------------+---------+-----------+--------------+--------------------+--------------+--------------+-------------------+------------------+-----------------------+-----------------------+--------------+---------------+--------------+---------------+--------------+----------------------+----------------+-----------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| 0 | s3://.../iceberg_table/data/id=2/00000-16-79ef2fd7-9997-47eb-a91a-9f7af8201315-0-00002.parquet | PARQUET | 0 | {"id":2} | 1 | 611 | {1:36, 2:39} | {1:1, 2:1} | {1:0, 2:0} | {} | {1:" ", 2:"Bob"} | {1:" ", 2:"Bob"} | NULL | [4] | NULL | 0 | NULL | NULL | NULL | NULL | {"id":{"column_size":36, "value_count":1, "null_value_count":0, "nan_value_count":null, "lower_bound":2, "upper_bound":2}, "name":{"column_size":39, "value_count":1, "null_value_count":0, "nan_value_count":null, "lower_bound":"Bob", "upper_bound":"Bob"}} |
| 0 | s3://.../iceberg_table/data/id=4/00000-16-79ef2fd7-9997-47eb-a91a-9f7af8201315-0-00004.parquet | PARQUET | 0 | {"id":4} | 1 | 618 | {1:36, 2:40} | {1:1, 2:1} | {1:0, 2:0} | {} | {1:" ", 2:"Dave"} | {1:" ", 2:"Dave"} | NULL | [4] | NULL | 0 | NULL | NULL | NULL | NULL | {"id":{"column_size":36, "value_count":1, "null_value_count":0, "nan_value_count":null, "lower_bound":4, "upper_bound":4}, "name":{"column_size":40, "value_count":1, "null_value_count":0, "nan_value_count":null, "lower_bound":"Dave", "upper_bound":"Dave"}} |
| 0 | s3://.../iceberg_table/data/id=6/00000-16-79ef2fd7-9997-47eb-a91a-9f7af8201315-0-00006.parquet | PARQUET | 0 | {"id":6} | 1 | 625 | {1:36, 2:41} | {1:1, 2:1} | {1:0, 2:0} | {} | {1:" ", 2:"Frank"} | {1:" ", 2:"Frank"} | NULL | [4] | NULL | 0 | NULL | NULL | NULL | NULL | {"id":{"column_size":36, "value_count":1, "null_value_count":0, "nan_value_count":null, "lower_bound":6, "upper_bound":6}, "name":{"column_size":41, "value_count":1, "null_value_count":0, "nan_value_count":null, "lower_bound":"Frank", "upper_bound":"Frank"}} |
| 0 | s3://.../iceberg_table/data/id=8/00000-16-79ef2fd7-9997-47eb-a91a-9f7af8201315-0-00008.parquet | PARQUET | 0 | {"id":8} | 1 | 625 | {1:36, 2:41} | {1:1, 2:1} | {1:0, 2:0} | {} | {1:" ", 2:"Heidi"} | {1:" ", 2:"Heidi"} | NULL | [4] | NULL | 0 | NULL | NULL | NULL | NULL | {"id":{"column_size":36, "value_count":1, "null_value_count":0, "nan_value_count":null, "lower_bound":8, "upper_bound":8}, "name":{"column_size":41, "value_count":1, "null_value_count":0, "nan_value_count":null, "lower_bound":"Heidi", "upper_bound":"Heidi"}} |
| 0 | s3://.../iceberg_table/data/id=10/00000-16-79ef2fd7-9997-47eb-a91a-9f7af8201315-0-00010.parquet | PARQUET | 0 | {"id":10} | 1 | 618 | {1:36, 2:40} | {1:1, 2:1} | {1:0, 2:0} | {} | {1:" ", 2:"Judy"} | {1:" ", 2:"Judy"} | NULL | [4] | NULL | 0 | NULL | NULL | NULL | NULL | {"id":{"column_size":36, "value_count":1, "null_value_count":0, "nan_value_count":null, "lower_bound":10, "upper_bound":10}, "name":{"column_size":40, "value_count":1, "null_value_count":0, "nan_value_count":null, "lower_bound":"Judy", "upper_bound":"Judy"}} |
+---------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------------+---------+-----------+--------------+--------------------+--------------+--------------+-------------------+------------------+-----------------------+-----------------------+--------------+---------------+--------------+---------------+--------------+----------------------+----------------+-----------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+

files システムテーブルと同様に、次のシステムテーブルを使用して特定の種類のファイル情報もクエリできます。

-- Query data files for the current snapshot
SELECT * FROM iceberg_table$data_files;

-- Query delete files for the current snapshot
SELECT * FROM iceberg_table$delete_files;

-- Query all files (including data and delete files) from all snapshots
SELECT * FROM iceberg_table$all_files;

-- Query data files from all snapshots
SELECT * FROM iceberg_table$all_data_files;

-- Query delete files from all snapshots
SELECT * FROM iceberg_table$all_delete_files;

これらのテーブルの結果形式は files システムテーブルに似ていますが、それぞれデータファイルまたは削除ファイルに特化しています。接頭辞 all_ が付くシステムテーブルには、現在のスナップショットだけでなく、すべてのスナップショットのファイルが含まれます。

注:特定の種類のファイルがテーブルに存在しない場合(たとえば削除ファイルがないテーブルで delete_files をクエリする場合)、結果が空になることがあります。

history​

テーブルのすべての履歴を表示します。

SELECT * FROM iceberg_table$history;

結果:

+----------------------------+---------------------+---------------------+---------------------+
| made_current_at | snapshot_id | parent_id | is_current_ancestor |
+----------------------------+---------------------+---------------------+---------------------+
| 2025-06-12 22:29:16.357000 | 1851184769713369003 | NULL | 1 |
| 2025-06-12 22:29:39.922000 | 4890031351138056789 | 1851184769713369003 | 1 |
+----------------------------+---------------------+---------------------+---------------------+

labels​

この機能はバージョン 5.0.0 以降でサポートされています。

REST Catalog が Iceberg テーブルに提供するテーブルレベル(object)とフィールドレベル(field)のラベルを表示します。ラベルのキーと値の組ごとに一行を返します。テーブルの所有者やフィールドのデータ分類などの確認に使用できます。

このシステムテーブルは、iceberg.catalog.type が rest の場合にのみ利用できます。Doris 側で追加の設定は不要です。REST Catalog サービスはテーブルのデータロード時にラベルを返します。ラベルの作成と変更はサービスプロバイダーを通じて行います。これらのラベルはテーブルまたはフィールドを説明するもので、refs に表示されるスナップショットの Tag とは異なります。

フィールド:

フィールド型説明
scopeTEXTラベルのスコープ。テーブルレベルのラベルは object、フィールドレベルのラベルは field。
field_idINTIceberg のフィールド ID。テーブルレベルのラベルでは NULL。
field_nameTEXT現在のテーブルスキーマに照らして解決したフィールド名。ネストしたフィールドでは address.city のようにフルパスを使用します。テーブルレベルのラベル、またはフィールド ID が現在のスキーマに存在しない場合は NULL。
keyTEXTラベルのキー。key は Doris の予約語なので、このカラムを SQL で明示的に参照する際はバッククォートで囲みます。
valueTEXTラベルの値。

クエリ例:

次の例では、Iceberg REST Catalog の説明に従って iceberg_ctl Catalog を設定済みであり、iceberg_db.iceberg_tbl テーブルが存在し、現在のユーザーにクエリ権限があることを前提とします。REST Catalog サービスは次のラベルを設定し、返します。

  • テーブルレベルのラベル:owner=team-a。
  • email フィールド(フィールド ID 2)のラベル:classification=pii。
  • ネストした address.city フィールド(フィールド ID 5)のラベル:classification=location。

すべてのラベルをスコープ、フィールド ID、ラベルキーの順に取得します。

SELECT * FROM iceberg_ctl.iceberg_db.iceberg_tbl$labels
ORDER BY scope, field_id, `key`;

結果:

+--------+----------+--------------+----------------+----------+
| scope | field_id | field_name | key | value |
+--------+----------+--------------+----------------+----------+
| field | 2 | email | classification | pii |
| field | 5 | address.city | classification | location |
| object | NULL | NULL | owner | team-a |
+--------+----------+--------------+----------------+----------+

pii に分類されたフィールドを検索します。

SELECT field_name, `key`, value
FROM iceberg_ctl.iceberg_db.iceberg_tbl$labels
WHERE scope = 'field' AND `key` = 'classification' AND value = 'pii';

結果:

+------------+----------------+-------+
| field_name | key | value |
+------------+----------------+-------+
| email | classification | pii |
+------------+----------------+-------+

キャッシュと更新:

ラベルはテーブルメタデータとともにキャッシュされ、meta.cache.iceberg.table.ttl-second の設定に従います。サービス側のラベルを変更した後、更新後のラベルを取得するには、$labels をクエリする前に元のテーブルを更新してください。

REFRESH TABLE iceberg_ctl.iceberg_db.iceberg_tbl;

更新後、次の $labels クエリではテーブルが再度データロードされ、サービスから返されたラベルが読み取られます。meta.cache.iceberg.table.ttl-second を 0 に設定すると、テーブルメタデータキャッシュが無効になり、クエリのたびにラベルが再データロードされます。キャッシュ設定については メタデータキャッシュ を参照してください。

注意事項:

  • REST Catalog サービスがラベルを返さない場合、クエリ結果は空になります。スナップショットがないテーブルでも、サービスがラベルを提供すればラベルを返せます。COUNT(*) が数えるのは、元のテーブルのデータ行ではなく、ラベルのキーと値の組です。
  • ラベルはスナップショットとともにバージョン管理されません。$labels に FOR VERSION AS OF を使用しても過去のラベルは取得されず、現在データロードされたテーブルのラベルが返され、フィールド名も現在のスキーマに対して解決されます。
  • フィールドラベルはフィールド ID に関連付けられます。フィールド名を変更すると、field_name には新しい名前が表示されます。フィールドを削除した後もサービスがそのラベルを返す場合、field_id は保持され、field_name は NULL になります。
  • REST 以外の Catalog は $labels に対応しておらず、クエリすると Unknown sys table エラーになります。サーバー側でのスキャン計画を必要とする REST Catalog も、このシステムテーブルには対応していません。

manifests​

テーブルのマニフェストファイル情報を表示します。

SELECT * FROM iceberg_table$manifests;

結果:

+---------+------------------------------------------------------------------------------------------------------------------------------------------------+--------+-------------------+---------------------+------------------------+---------------------------+--------------------------+--------------------------+-----------------------------+----------------------------+--------------------------------------------------------------------------------+
| content | path | length | partition_spec_id | added_snapshot_id | added_data_files_count | existing_data_files_count | deleted_data_files_count | added_delete_files_count | existing_delete_files_count | deleted_delete_files_count | partition_summaries |
+---------+------------------------------------------------------------------------------------------------------------------------------------------------+--------+-------------------+---------------------+------------------------+---------------------------+--------------------------+--------------------------+-----------------------------+----------------------------+--------------------------------------------------------------------------------+
| 0 | s3://.../iceberg_table/metadata/3194eb8b-5ea4-4cbe-95ba-073229458e7b-m0.avro | 7138 | 0 | 4890031351138056789 | 0 | 5 | 5 | 0 | 0 | 0 | [{"contains_null":0, "contains_nan":0, "lower_bound":"1", "upper_bound":"10"}] |
+---------+------------------------------------------------------------------------------------------------------------------------------------------------+--------+-------------------+---------------------+------------------------+---------------------------+--------------------------+--------------------------+-----------------------------+----------------------------+--------------------------------------------------------------------------------+

all_manifests​

この機能はバージョン 4.0.4 以降でサポートされています。

テーブルのすべての有効なスナップショットについて、マニフェストファイル情報を表示します。

all_manifests と manifests の構造は同じです。all_manifests はすべての有効なスナップショットのマニフェストファイルを含み、manifests は現在のスナップショットのマニフェストファイルのみを含みます。

SELECT * FROM iceberg_table$all_manifests;

結果形式は manifests システムテーブルと同じです。

metadata_log_entries​

テーブルのメタデータログを表示します。

SELECT * FROM iceberg_table$metadata_log_entries;

結果:

+----------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------+------------------+------------------------+
| timestamp | file | latest_snapshot_id | latest_schema_id | latest_sequence_number |
+----------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------+------------------+------------------------+
| 2025-06-12 22:29:06.948000 | s3://.../iceberg_table/metadata/00000-e373aa16-15f1-4e69-ae7d-5ed64199cf9a.metadata.json | NULL | NULL | NULL |
| 2025-06-12 22:29:16.357000 | s3://.../iceberg_table/metadata/00001-bbc8e244-e41c-4958-92f4-63b8c3ee1196.metadata.json | 1851184769713369003 | 0 | 1 |
| 2025-06-12 22:29:39.922000 | s3://.../iceberg_table/metadata/00002-7dc00d6a-6269-4200-9d28-5f8c1c6b9f99.metadata.json | 4890031351138056789 | 0 | 2 |
+----------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------+------------------+------------------------+

partitions​

テーブルのパーティションを表示します。

SELECT * FROM iceberg_table$partitions;

結果:

+-----------+---------+--------------+------------+-------------------------------+------------------------------+----------------------------+------------------------------+----------------------------+----------------------------+--------------------------+
| partition | spec_id | record_count | file_count | total_data_file_size_in_bytes | position_delete_record_count | position_delete_file_count | equality_delete_record_count | equality_delete_file_count | last_updated_at | last_updated_snapshot_id |
+-----------+---------+--------------+------------+-------------------------------+------------------------------+----------------------------+------------------------------+----------------------------+----------------------------+--------------------------+
| {"id":8} | 0 | 1 | 1 | 625 | 0 | 0 | 0 | 0 | 2025-06-12 22:29:16.357000 | 1851184769713369003 |
| {"id":6} | 0 | 1 | 1 | 625 | 0 | 0 | 0 | 0 | 2025-06-12 22:29:16.357000 | 1851184769713369003 |
| {"id":10} | 0 | 1 | 1 | 618 | 0 | 0 | 0 | 0 | 2025-06-12 22:29:16.357000 | 1851184769713369003 |
| {"id":4} | 0 | 1 | 1 | 618 | 0 | 0 | 0 | 0 | 2025-06-12 22:29:16.357000 | 1851184769713369003 |
| {"id":2} | 0 | 1 | 1 | 611 | 0 | 0 | 0 | 0 | 2025-06-12 22:29:16.357000 | 1851184769713369003 |
+-----------+---------+--------------+------------+-------------------------------+------------------------------+----------------------------+------------------------------+----------------------------+----------------------------+--------------------------+

注:

  1. パーティション化されていないテーブルでは、partitions テーブルに partition と spec_id のフィールドはありません。
  2. partitions テーブルには、現在のスナップショットでデータファイルまたは削除ファイルを含むパーティションが表示されます。ただし、削除ファイルは適用されないため、パーティション内のすべてのデータ行が削除ファイルによって削除対象とされていても、そのパーティションが表示される場合があります。

refs​

テーブルで既知のすべてのスナップショット参照(ブランチとタグ)を表示します。

SELECT * FROM iceberg_table$refs;

結果:

+------+--------+---------------------+-------------------------+-----------------------+------------------------+
| name | type | snapshot_id | max_reference_age_in_ms | min_snapshots_to_keep | max_snapshot_age_in_ms |
+------+--------+---------------------+-------------------------+-----------------------+------------------------+
| main | BRANCH | 4890031351138056789 | NULL | NULL | NULL |
+------+--------+---------------------+-------------------------+-----------------------+------------------------+

snapshots​

テーブルのすべてのスナップショットを表示します。

SELECT * FROM iceberg_table$snapshots;

結果:

+----------------------------+---------------------+---------------------+-----------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| committed_at | snapshot_id | parent_id | operation | manifest_list | summary |
+----------------------------+---------------------+---------------------+-----------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| 2025-06-12 22:29:16.357000 | 1851184769713369003 | NULL | append | s3://.../iceberg_table/metadata/snap-1851184769713369003-1-82059f57-821a-4983-b083-002cc2cde313.avro | {"spark.app.id":"application_1738810850199_0472", "added-data-files":"10", "added-records":"10", "added-files-size":"6200", "changed-partition-count":"10", "total-records":"10", "total-files-size":"6200", "total-data-files":"10", "total-delete-files":"0", "total-position-deletes":"0", "total-equality-deletes":"0"} |
| 2025-06-12 22:29:39.922000 | 4890031351138056789 | 1851184769713369003 | overwrite | s3://.../iceberg_table/metadata/snap-4890031351138056789-1-3194eb8b-5ea4-4cbe-95ba-073229458e7b.avro | {"spark.app.id":"application_1738810850199_0472", "deleted-data-files":"5", "deleted-records":"5", "removed-files-size":"3103", "changed-partition-count":"5", "total-records":"5", "total-files-size":"3097", "total-data-files":"5", "total-delete-files":"0", "total-position-deletes":"0", "total-equality-deletes":"0"} |
+----------------------------+---------------------+---------------------+-----------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+

書き込み操作​

INSERT INTO​

INSERT 操作は、書き込み先テーブルにデータを追加します。

例:

INSERT INTO iceberg_tbl VALUES (val1, val2, val3, val4);
INSERT INTO iceberg.iceberg_db.iceberg_tbl SELECT col1, col2 FROM internal.db1.tbl1;

INSERT INTO iceberg_tbl(col1, col2) VALUES (val1, val2);
INSERT INTO iceberg_tbl(col1, col2, partition_col1, partition_col2) VALUES (1, 2, 'beijing', '2023-12-12');

バージョン 3.1.0 以降、指定したブランチへのデータ書き込みに対応しています。

INSERT INTO iceberg_tbl@branch(b1) values (val1, val2, val3, val4);
INSERT INTO iceberg_tbl@branch(b1) (col3, col4) values (val3, val4);

INSERT OVERWRITE​

INSERT OVERWRITE 操作は、テーブル内の既存データを新しいデータで完全に置き換えます。

INSERT OVERWRITE TABLE iceberg_tbl VALUES (val1, val2, val3, val4);
INSERT OVERWRITE TABLE iceberg.iceberg_db.iceberg_tbl(col1, col2) SELECT col1, col2 FROM internal.db1.tbl1;

バージョン 3.1.0 以降、指定したブランチへのデータ書き込みに対応しています。

INSERT OVERWRITE TABLE iceberg_tbl@branch(b1) values (val1, val2, val3, val4);
INSERT OVERWRITE TABLE iceberg_tbl@branch(b1) (col3, col4) values (val3, val4);

バージョン 4.1.0 以降、静的パーティション(または混合パーティション)へのデータ書き込みに対応しています。

-- Full Static Partition
INSERT OVERWRITE TABLE iceberg_tbl PARTITION (dt='2025-01-25', region='bj')
SELECT id, name FROM source_table;

-- Hybrid Partition Mode: "dt" is static, "region" comes from SELECT dynamically
INSERT OVERWRITE TABLE iceberg_tbl PARTITION (dt='2025-01-25')
SELECT id, name, region FROM source_table;

CTAS​

CTAS(Create Table As Select)ステートメントを使用して Iceberg テーブルを作成し、データを書き込めます。

CREATE TABLE iceberg_ctas AS SELECT * FROM other_table;

CTAS では、ファイル形式、パーティション分割、その他のプロパティを指定できます。

CREATE TABLE iceberg_ctas
PARTITION BY LIST (pt1, pt2) ()
AS SELECT col1, pt1, pt2 FROM part_ctas_src WHERE col1 > 0;

CREATE TABLE iceberg.iceberg_db.iceberg_ctas (col1, col2, pt1)
PARTITION BY LIST (pt1) ()
PROPERTIES (
'write-format'='parquet',
'compression-codec'='zstd'
)
AS SELECT col1, pt1 AS col2, pt2 AS pt1 FROM test_ctas.part_ctas_src WHERE col1 > 0;

INSERT INTO BRANCH​

3.1.0 以降

INSERT INTO iceberg_table@branch(b1) SELECT * FROM other_table;
INSERT OVERWRITE TABLE iceberg_table@branch(b1) SELECT * FROM other_table;

DELETE​

ヒント

これは実験的な機能で、バージョン 4.1.0 以降でサポートされています。

DELETE 操作は、指定した条件を満たす Iceberg テーブルのデータ行を削除します。内部では主に次の仕組みを使用します。V2 形式のテーブルでは Position Delete ファイルを、V3 形式のテーブルでは Puffin 形式の Deletion Vectors ファイルを書き込みます。

前提条件:

  • Iceberg テーブルの形式バージョン(format-version)は 2 以上である必要があります。V1 形式のテーブルは DELETE 操作に対応していません。

構文:

DELETE FROM iceberg_tbl WHERE <condition>;

例:

-- Delete a single row
DELETE FROM iceberg_tbl WHERE id = 1;

-- Delete using multiple conditions
DELETE FROM iceberg_tbl WHERE age > 30 AND name = 'Bob';

-- Delete using a subquery
DELETE FROM iceberg_tbl WHERE id IN (SELECT id FROM other_table WHERE status = 'inactive');

パーティション化されたテーブルでも使用方法は同じです。

DELETE FROM iceberg_partition_tbl WHERE id = 10;

UPDATE​

ヒント

これは実験的な機能で、バージョン 4.1.0 以降でサポートされています。

UPDATE 操作は、指定した条件を満たす Iceberg テーブルのデータ行を変更します。内部的には、まず削除追跡情報(V2 では Position Delete ファイル、V3 では Puffin 形式の Deletion Vectors)を書き込んで古いデータ行を無効にし、その後、更新後の新しいデータファイルを追加します(V3 形式のオプションが有効な場合、新しく挿入された行の追跡値 _last_updated_sequence_number は自動的に進みます)。

前提条件:

  • Iceberg テーブルの形式バージョン(format-version)は 2 以上である必要があります。V1 形式のテーブルは UPDATE 操作に対応していません。

構文:

UPDATE iceberg_tbl SET <column1> = <value1> [, <column2> = <value2>, ...] WHERE <condition>;

例:

-- Update a single column
UPDATE iceberg_tbl SET name = 'Alice_new' WHERE id = 1;

-- Update multiple columns
UPDATE iceberg_tbl SET name = 'Updated', age = 28 WHERE id = 2;

-- Update using expressions
UPDATE iceberg_tbl SET age = age * 2 + 1, name = concat(name, '-modified') WHERE id = 3;

-- Update using a subquery as condition
UPDATE iceberg_tbl SET name = 'UpdatedViaSubquery' WHERE id IN (SELECT id FROM other_table);

パーティション化されたテーブルでも使用方法は同じです。

UPDATE iceberg_partition_tbl SET name = 'Updated' WHERE id = 10;

MERGE INTO​

ヒント

これは実験的な機能で、バージョン 4.1.0 以降でサポートされています。

MERGE INTO 操作は、ソースデータと書き込み先の Iceberg テーブルを照合し、照合結果に応じて挿入、更新、削除を行います。データ同期や増分更新などに適しています。

前提条件:

  • Iceberg テーブルの形式バージョン(format-version)は 2 以上である必要があります。V1 形式のテーブルは MERGE INTO 操作に対応していません。

構文:

MERGE INTO target_table t
USING <source> s
ON <merge_condition>
[WHEN MATCHED [AND <condition>] THEN DELETE]
[WHEN MATCHED [AND <condition>] THEN UPDATE SET <column1> = <value1> [, ...]]
[WHEN NOT MATCHED [AND <condition>] THEN INSERT (<columns>) VALUES (<values>)]

<source> にはサブクエリまたは別のテーブルを指定できます。

例:

  • すべての照合操作(更新、削除、挿入)を行う例:

    MERGE INTO iceberg_tbl t
    USING (
    SELECT 1 AS id, 'Alice_new' AS name, 26 AS age, 'U' AS flag
    UNION ALL
    SELECT 2, 'Bob', 30, 'D'
    UNION ALL
    SELECT 4, 'Dora', 28, 'I'
    ) s
    ON t.id = s.id
    WHEN MATCHED AND s.flag = 'D' THEN DELETE
    WHEN MATCHED THEN UPDATE SET
    name = s.name,
    age = s.age
    WHEN NOT MATCHED THEN INSERT (id, name, age)
    VALUES (s.id, s.name, s.age);

    上の例では、次のように処理されます。

    • id = 2 の行は flag = 'D' であるため削除されます。
    • id = 1 の行は新しい name と age に更新されます。
    • id = 4 の行は書き込み先テーブルに存在しないため挿入されます。
  • 一致した行の更新のみを行う例:

    MERGE INTO iceberg_tbl t
    USING (SELECT 1 AS id, 'Alice_matched' AS name, 26 AS age) s
    ON t.id = s.id
    WHEN MATCHED THEN UPDATE SET name = s.name, age = s.age;
  • 一致しない行の挿入のみを行う例:

    MERGE INTO iceberg_tbl t
    USING (SELECT 4 AS id, 'Dora' AS name, 40 AS age) s
    ON t.id = s.id
    WHEN NOT MATCHED THEN INSERT (id, name, age) VALUES (s.id, s.name, s.age);
  • サブクエリをデータソースとして使用する例:

    MERGE INTO iceberg_tbl t
    USING (SELECT id FROM other_table WHERE id = 2) s
    ON t.id = s.id
    WHEN MATCHED THEN UPDATE SET name = 'UpdatedViaSubquery';
  • パーティション化されたテーブルでの MERGE INTO 操作:

    MERGE INTO iceberg_partition_tbl t
    USING (
    SELECT 1 AS id, 'Alice_new' AS name, 26 AS age, DATE '2024-01-01' AS dt, 'U' AS flag
    UNION ALL
    SELECT 2, 'Bob', 30, DATE '2024-01-02', 'D'
    UNION ALL
    SELECT 4, 'Dora', 28, DATE '2024-01-04', 'I'
    ) s
    ON t.id = s.id
    WHEN MATCHED AND s.flag = 'D' THEN DELETE
    WHEN MATCHED THEN UPDATE SET
    name = s.name,
    age = s.age
    WHEN NOT MATCHED THEN INSERT (id, name, age, dt)
    VALUES (s.id, s.name, s.age, s.dt);

注意事項:

  1. 上記の三つの操作(DELETE、UPDATE、MERGE INTO)は、いずれも Iceberg テーブルの形式バージョン(format-version)が 2 以上であることが必要です。V1 形式のテーブルで実行すると、must have format version 2 or higher for position deletes というエラーになります。V3 形式のテーブルでは、元の Position Delete データの代わりに Puffin 形式の Deletion Vectors を使用するほか、内容の更新を伴う場合は、書き込まれるレコードの Lineage ライフサイクル属性(_last_updated_sequence_number)も自動的に調整されます。
  2. これらの操作は Parquet と ORC の両方のファイル形式に対応しています。
  3. 並行書き込み時には、Iceberg は楽観的同時実行制御を提供します。書き込みが競合すると、トランザクション競合の例外が発生する場合があります。
  4. UPDATE 操作では、単独で実行する場合も MERGE INTO 内で実行する場合も、age = age * 2 + 1 や name = concat(name, '-modified') などの式や関数を使用できます。
  5. これらの操作は、パーティション化されたテーブルにも、パーティション化されていないテーブルにも適用できます。
  6. バージョン 4.1.4 以降、MERGE INTO はソースと書き込み先テーブルの照合関係を検証します。同じ書き込み先行に複数のソース行が一致した場合、結果が非決定的になる代わりに、ステートメントは multiple source rows matched the same target row で失敗します。1 対多の一致が想定される場合は、先にソース側で重複を除去してください。
  • BE(Backend)

    パラメータ名デフォルト値説明
    iceberg_sink_max_file_size1GBデータファイルの最大サイズです。書き込まれたデータがこのサイズを超えると、現在のファイルを閉じ、新しいファイルを作成して書き込みを続けます。
    table_sink_partition_write_max_partition_nums_per_writer128BE ノード上の各インスタンスが書き込めるパーティション数の上限です。
    table_sink_non_partition_write_scaling_data_processed_threshold25MBパーティション化されていないテーブルで、書き込みのスケーリングを開始するデータ量のしきい値です。table_sink_non_partition_write_scaling_data_processed_threshold のデータ量が追加されるたびに、新しいライター(インスタンス)を使用します。この仕組みはデータ量に応じてライター数を調整し、少量のデータではリソース消費とファイル数を抑えながら、スループットを高めます。
    table_sink_partition_write_min_data_processed_rebalance_threshold25MBパーティション化されたテーブルで再バランスを開始する最小データ量のしきい値です。現在までの累積データ量 - 前回の再バランス以降のデータ量 >= table_sink_partition_write_min_data_processed_rebalance_threshold の場合に再バランスを開始します。ファイルサイズの差が大きい場合は、このしきい値を下げるとバランスが改善する可能性がありますが、再バランスのコストが増え、パフォーマンスに影響する場合があります。
    table_sink_partition_write_min_partition_data_processed_rebalance_threshold再バランスを開始するパーティションごとの最小データ量のしきい値です。現在のパーティションデータ量 >= しきい値 * そのパーティションにすでに割り当てられたタスク数 の場合に再バランスを開始します。ファイルサイズの差が大きい場合は、このしきい値を下げるとバランスが改善する可能性がありますが、再バランスのコストが増え、パフォーマンスに影響する場合があります。

データベースとテーブルの管理​

データベースの作成と削除​

SWITCH ステートメントで目的の Catalog に切り替え、CREATE DATABASE コマンドを実行できます。

SWITCH iceberg;
CREATE DATABASE [IF NOT EXISTS] iceberg_db;

完全修飾名を使用してデータベースを作成したり、場所を指定したりすることもできます(現在、場所の指定に対応するのは HMS タイプの Catalog のみです)。例:

CREATE DATABASE [IF NOT EXISTS] iceberg.iceberg_db;

CREATE DATABASE [IF NOT EXISTS] iceberg.iceberg_db
PROPERTIES ('location'='hdfs://172.21.16.47:4007/path/to/db/');

SHOW CREATE DATABASE コマンドでデータベースの場所を確認できます。

mysql> SHOW CREATE DATABASE iceberg_db;
+-------------+-------------------------------------------------------------------------------------------------+
| Database | Create Database |
+-------------+-------------------------------------------------------------------------------------------------+
| iceberg_db | CREATE DATABASE iceberg_db LOCATION 'hdfs://172.21.16.47:4007/usr/hive/warehouse/iceberg_db.db' |
+-------------+-------------------------------------------------------------------------------------------------+

データベースを削除するには、次を実行します。

DROP DATABASE [IF EXISTS] iceberg.iceberg_db;
注意

Iceberg データベースを削除するには、先にそのデータベース内のすべてのテーブルを削除する必要があります。そうしないとエラーになります。

テーブルの作成と削除​

  • テーブルの作成

    Doris は、パーティション化された Iceberg テーブルと、パーティション化されていない Iceberg テーブルの両方を作成できます。

    例:

    -- Create unpartitioned iceberg table
    CREATE TABLE unpartitioned_table (
    `col1` BOOLEAN COMMENT 'col1',
    `col2` INT COMMENT 'col2',
    `col3` BIGINT COMMENT 'col3',
    `col4` FLOAT COMMENT 'col4',
    `col5` DOUBLE COMMENT 'col5',
    `col6` DECIMAL(9,4) COMMENT 'col6',
    `col7` STRING COMMENT 'col7',
    `col8` DATE COMMENT 'col8',
    `col9` DATETIME COMMENT 'col9'
    )
    PROPERTIES (
    'write-format'='parquet'
    );

    -- Create partitioned iceberg table
    -- The partition columns must be in table's column definition list
    CREATE TABLE partition_table (
    `ts` DATETIME COMMENT 'ts',
    `col1` BOOLEAN COMMENT 'col1',
    `col2` INT COMMENT 'col2',
    `col3` BIGINT COMMENT 'col3',
    `col4` FLOAT COMMENT 'col4',
    `col5` DOUBLE COMMENT 'col5',
    `col6` DECIMAL(9,4) COMMENT 'col6',
    `col7` STRING COMMENT 'col7',
    `col8` DATE COMMENT 'col8',
    `col9` DATETIME COMMENT 'col9',
    `pt1` STRING COMMENT 'pt1',
    `pt2` STRING COMMENT 'pt2'
    )
    PARTITION BY LIST (day(ts), pt1, pt2) ()
    PROPERTIES (
    'write-format'='orc',
    'compression-codec'='zlib'
    );

    バージョン 4.1.0 以降、Doris は Iceberg テーブルの作成時にソートカラムを指定できます。データの書き込み時に、指定したソートカラムに従ってデータが並べ替えられ、クエリ性能の向上につながります。

    CREATE TABLE ordered_table (
    `id` int NULL,
    `name` text NULL,
    `score` double NULL,
    `create_time` datetimev2(6) NULL
    )
    ORDER BY (`id` ASC NULLS FIRST, `score` DESC NULLS LAST)
    PROPERTIES (
    "write-format" = "parquet",
    "write.parquet.compression-codec" = "zstd"
    );
    • ソートカラムを指定しない場合、書き込み時にソートは行われません。
    • デフォルトのソート順は ASC NULLS FIRST です。

    作成後は SHOW CREATE TABLE コマンドで Iceberg テーブルの作成ステートメントを確認できます。パーティション関数の詳細は「パーティション分割」を参照してください。

  • テーブルの削除

    DROP TABLE ステートメントで Iceberg テーブルを削除できます。テーブルを削除すると、パーティションデータを含むデータも削除されます。

    例:

    DROP TABLE [IF EXISTS] iceberg_tbl;
  • カラム型のマッピング

    「カラム型のマッピング」を参照してください。

  • パーティション分割

    Iceberg のパーティションの種類は、Doris の List パーティションに対応します。そのため、Doris で Iceberg のパーティション化テーブルを作成する際は List パーティションの構文を使用します。ただし、各パーティションを明示的に列挙する必要はありません。データの挿入時に、Doris がデータ値に基づいて対応する Iceberg パーティションを自動的に作成します。

    • 単一カラムまたは複数カラムによるパーティション化テーブルの作成に対応します。

    • パーティション変換関数に対応し、Iceberg の暗黙的なパーティション分割とパーティション進化を利用できます。Iceberg の具体的なパーティション変換関数については、Iceberg partition transforms を参照してください。

      • year(ts) または years(ts)

      • month(ts) または months(ts)

      • day(ts) または days(ts) または date(ts)

      • hour(ts) または hours(ts) または date_hour(ts)

      • bucket(N, col)

      • truncate(L, col)

  • ファイル形式

    • Parquet(デフォルト)

      Doris が作成した Iceberg テーブルでは、Datetime は timestamp_ntz 型に対応します。

      3.1.0 より後のバージョンでは、Datetime 型を Parquet ファイルに書き込む際の物理型に INT96 ではなく INT64 を使用します。

      また、他のシステムが作成した Iceberg テーブルでは、timestamp と timestamp_ntz の両方が Doris の Datetime 型にマッピングされますが、書き込み時には実際の型に基づいてタイムゾーン処理の要否を判断します。

    • ORC

  • 圧縮形式

    • Parquet:snappy、zstd(デフォルト)、plain(圧縮なし)。

    • ORC:snappy、zlib(デフォルト)、zstd、plain(圧縮なし)。

  • ストレージ媒体

    • HDFS

    • オブジェクトストレージ

スキーマ変更​

3.1.0 以降、Doris は Iceberg テーブルのスキーマ変更に対応しており、ALTER TABLE ステートメントで変更できます。

対応するスキーマ変更操作は次のとおりです。

  • カラム名の変更

    RENAME COLUMN 句でカラム名を変更します。バージョン 4.1.4 以降は、ネストした型内のカラム名も変更でき、TO キーワードを省略できます。

    ALTER TABLE iceberg_table RENAME COLUMN old_col_name TO new_col_name;

    -- Supported since 4.1.4: TO can be omitted
    ALTER TABLE iceberg_table RENAME COLUMN old_col_name new_col_name;

    -- Supported since 4.1.4: rename a nested field
    ALTER TABLE iceberg_table RENAME COLUMN s.old_field TO new_field;
  • カラムの追加

    ADD COLUMN で新しいカラムを追加します。バージョン 4.1.4 以降は、ドット区切りのパス(例:s.new_field)を使用してネストした型(STRUCT)に新しいカラムを追加できます。新しく追加するネストしたフィールドは NULL を許容する必要があります。

    新しいカラムを追加する際には、NULL 許容属性、デフォルト値、コメント、カラム位置を指定できます。

    ALTER TABLE iceberg_table ADD COLUMN col_name col_type [NULL|NOT NULL, [DEFAULT default_value, [COMMENT 'comment', [FIRST|AFTER col_name]]]];

    例:

    ALTER TABLE iceberg_table ADD COLUMN new_col STRING NOT NULL DEFAULT 'default_value' COMMENT 'This is a new col' AFTER old_col;
  • 複数カラムの追加

    ADD COLUMN で複数のカラムを追加することもできます。新しいカラムはテーブルの末尾に追加されます。複数カラムの追加では、カラム位置の指定はサポートされません。ネストした型への新しいカラムの追加もサポートされません。

    各カラムの構文は、単一カラムを追加する場合と同じです。

    ALTER TABLE iceberg_table ADD COLUMN (col_name1 col_type1 [NULL|NOT NULL, [DEFAULT default_value, [COMMENT 'comment']]], col_name2 col_type2 [NULL|NOT NULL, [DEFAULT default_value, [COMMENT 'comment']]] ...);
  • カラムの削除

    DROP COLUMN でカラムを削除します。バージョン 4.1.4 以降は、ドット区切りのパスを使用してネストした型内のカラムも削除できます。

    ALTER TABLE iceberg_table DROP COLUMN col_name;

    -- Supported since 4.1.4: drop a nested field
    ALTER TABLE iceberg_table DROP COLUMN s.field_name;
  • カラムの変更

    MODIFY COLUMN ステートメントで、型、NULL 許容属性、デフォルト値、コメント、カラム位置などのカラム属性を変更します。

    バージョン 4.0.4 以降、Doris は複合型(STRUCT、ARRAY、MAP)の変更に対応します。安全な型の昇格や struct フィールドの追加も含まれます。

    ネストした型でサポートされる安全な型の昇格:

    • INT -> BIGINT、LARGEINT
    • TINYINT -> SMALLINT、INT、BIGINT、LARGEINT
    • SMALLINT -> INT、BIGINT、LARGEINT
    • BIGINT -> LARGEINT
    • FLOAT -> DOUBLE
    • VARCHAR(n) -> VARCHAR(m)(m > n の場合)

    複合型の制約:

    • 新しいネストしたフィールドはすべて NULL を許容する必要があります。
    • 任意から必須への変更はできません。
    • 複合型のデフォルト値には NULL のみ指定できます。

    注:カラム属性を変更する際は、変更しない属性も元の値を明示的に指定してください。

    ALTER TABLE iceberg_table MODIFY COLUMN col_name col_type [NULL|NOT NULL, [DEFAULT default_value, [COMMENT 'comment', [FIRST|AFTER col_name]]]];

    例:

    CREATE TABLE iceberg_table (
    id INT,
    name STRING
    );
    -- Modify the id column type to BIGINT, set as NOT NULL, default value to 0, and add comment
    ALTER TABLE iceberg_table MODIFY COLUMN id BIGINT NOT NULL DEFAULT 0 COMMENT 'This is a modified id column';

    複合型を変更する例:

    -- Create Iceberg table with complex types
    CREATE TABLE iceberg_tbl (
    id BIGINT,
    user_info STRUCT<name:STRING, scores:ARRAY<INT>, age:INT>,
    dt STRING
    );

    -- Append a new field (email) to the STRUCT column
    ALTER TABLE iceberg_tbl MODIFY COLUMN user_info STRUCT<name:STRING, scores:ARRAY<INT>, age:INT, email:STRING>;

    -- Promote the nested ARRAY element type from INT to BIGINT
    ALTER TABLE iceberg_tbl MODIFY COLUMN user_info STRUCT<name:STRING, scores:ARRAY<BIGINT>, age:INT, email:STRING>;
  • カラムの並べ替え

    ORDER BY で新しいカラム順を指定して、カラムを並べ替えます。

    ALTER TABLE iceberg_table ORDER BY (col_name1, col_name2, ...);

ネストしたカラムのスキーマ変更(4.1.4+)​

バージョン 4.1.4 以降、ADD COLUMN、DROP COLUMN、MODIFY COLUMN、RENAME COLUMN はいずれもドット区切りのパス(例:a.b.c)を受け付け、ネストしたフィールドを直接操作できます。この機能が適用されるのはIceberg テーブルのみです。他の種類のテーブルで使用すると、Nested column path is only supported for Iceberg tables: ... が報告されます。

主な制限とエラー:

エラーメッセージ説明
New nested field '<path>' must be nullable新しく追加するネストしたフィールドは NULL を許容する必要があります。
Rollup is not supported for Iceberg column operationsRollup 句はサポートされません。
PROPERTIES are not supported for Iceberg column operationsPROPERTIES 句はサポートされません。
KEY is not supported for Iceberg ADD/MODIFY COLUMNKEY キーワードはサポートされません。
Generated columns are not supported for Iceberg ADD/MODIFY COLUMN生成カラムはサポートされません。
Modifying default values is not supported for Iceberg columns既存カラムのデフォルト値の変更はサポートされません。
ON UPDATE is not supported for Iceberg ADD COLUMNON UPDATE 句はサポートされません。
Modify column type from complex to primitive is not supported複合型からプリミティブ型への変更はサポートされません。
Cannot change MAP key type from ... / Cannot <op> MAP key nested columnMAP のキーの型の変更、および MAP のキーに対するネストしたカラム操作はサポートされません。
Iceberg does not support comments on collection element or value fieldsコレクション要素または MAP の値フィールドへのコメントはサポートされません。
Multiple Iceberg ALTER clauses are not supported when a statement ...ネストしたカラムを扱う場合、ステートメントに含められる ALTER 句は一つだけです。

パーティション進化​

バージョン 4.0.2 以降、Doris は ALTER ステートメントによる Iceberg テーブルの Partition Evolution に対応しています。

対応するパーティション変換は次のとおりです。

変換構文例
bucketbucket(N, column)bucket(16, id)
truncatetruncate(N, column)truncate(10, name)
yearyear(column)year(ts)
monthmonth(column)month(ts)
dayday(column)day(ts)
hourhour(column)hour(ts)
identitycolumncategory

対応する操作は次のとおりです。

  • パーティションキーの追加

    -- use optional AS keyword to specify a custom name for the partition field
    ALTER TABLE table_name ADD PARTITION KEY partition_transform [AS key_name];

    -- example
    ALTER TABLE prod.db.sample ADD PARTITION KEY bucket(16, id);
    ALTER TABLE prod.db.sample ADD PARTITION KEY truncate(4, data);
    ALTER TABLE prod.db.sample ADD PARTITION KEY year(ts);
    -- use optional AS keyword to specify a custom name for the partition field
    ALTER TABLE prod.db.sample ADD PARTITION KEY bucket(16, id) AS shard;
  • パーティションキーの削除

    ALTER TABLE table_name DROP PARTITION KEY partition_transform|key_name;

    -- example
    ALTER TABLE prod.db.sample DROP PARTITION KEY catalog;
    ALTER TABLE prod.db.sample DROP PARTITION KEY bucket(16, id);
    ALTER TABLE prod.db.sample DROP PARTITION KEY truncate(4, data);
    ALTER TABLE prod.db.sample DROP PARTITION KEY year(ts);
    ALTER TABLE prod.db.sample DROP PARTITION KEY shard;
  • パーティションキーの置換

    -- use optional AS keyword to specify a custom name for the partition field
    ALTER TABLE table_name REPLACE PARTITION KEY key_name WITH partition_transform [AS key_name];

    -- example
    ALTER TABLE prod.db.sample REPLACE PARTITION KEY ts_day WITH day(ts);
    -- use optional AS keyword to specify a custom name for the new partition field
    ALTER TABLE prod.db.sample REPLACE PARTITION KEY ts_day WITH day(ts) AS day_of_ts;

ブランチとタグの管理​

3.1.0 以降

  • ブランチの作成

    構文:

    ALTER TABLE [catalog.][database.]table_name
    CREATE [OR REPLACE] BRANCH [IF NOT EXISTS] <branch_name>
    [AS OF VERSION <snapshot_id>]
    [RETAIN <num> { DAYS | HOURS | MINUTES }]
    [WITH SNAPSHOT RETENTION { snapshotKeep | timeKeep }]

    snapshotKeep:
    <num> SNAPSHOTS [<num> { DAYS | HOURS | MINUTES }]

    timeKeep:
    <num> { DAYS | HOURS | MINUTES }

    例:

    -- Create branch "b1".
    ALTER TABLE tbl CREATE BRANCH b1;
    ALTER TABLE tb1 CREATE BRANCH IF NOT EXISTS b1;
    -- Create or replace branch "b1".
    ALTER TABLE tb1 CREATE OR REPLACE BRANCH b1;
    -- Create or replace branch "b1" based on snapshot "123456".
    ALTER TABLE tb1 CREATE OR REPLACE BRANCH b1 AS OF VERSION 123456;
    -- Create or replace branch "b1" based on snapshot "123456", branch retained for 1 day.
    ALTER TABLE tb1 CREATE OR REPLACE BRANCH b1 AS OF VERSION 123456 RETAIN 1 DAYS;
    -- Create branch "b1" based on snapshot "123456", branch retained for 30 days. Keep the latest 3 snapshots in the branch.
    ALTER TABLE tb1 CREATE BRANCH b1 AS OF VERSION 123456 RETAIN 30 DAYS WITH SNAPSHOT RETENTION 3 SNAPSHOTS;
    -- Create branch "b1" based on snapshot "123456", branch retained for 30 days. Snapshots in the branch are retained for at most 2 days.
    ALTER TABLE tb1 CREATE BRANCH b1 AS OF VERSION 123456 RETAIN 30 DAYS WITH SNAPSHOT RETENTION 2 DAYS;
    -- Create branch "b1" based on snapshot "123456", branch retained for 30 days. Keep the latest 3 snapshots in the branch, and snapshots in the branch are retained for at most 2 days.
    ALTER TABLE tb1 CREATE BRANCH b1 AS OF VERSION 123456 RETAIN 30 DAYS WITH SNAPSHOT RETENTION 3 SNAPSHOTS 2 DAYS;
  • ブランチの削除

    構文:

    ALTER TABLE [catalog.][database.]table_name
    DROP BRANCH [IF EXISTS] <branch_name>;

    例:

    ALTER TABLE tbl DROP BRANCH b1;
  • タグの作成

    構文:

    ALTER TABLE [catalog.][database.]table_name
    CREATE [OR REPLACE] TAG [IF NOT EXISTS] <tag_name>
    [AS OF VERSION <snapshot_id>]
    [RETAIN <num> { DAYS | HOURS | MINUTES }]

    例:

    -- Create tag "t1".
    ALTER TABLE tbl CREATE TAG t1;
    ALTER TABLE tb1 CREATE TAG IF NOT EXISTS t1;
    -- Create or replace tag "t1".
    ALTER TABLE tb1 CREATE OR REPLACE TAG t1;
    -- Create or replace tag "t1" based on snapshot "123456".
    ALTER TABLE tb1 CREATE OR REPLACE TAG b1 AS OF VERSION 123456;
    -- Create or replace tag "b1" based on snapshot "123456", tag retained for 1 day.
    ALTER TABLE tb1 CREATE OR REPLACE TAG b1 AS OF VERSION 123456 RETAIN 1 DAYS;
  • タグの削除

    構文:

    ALTER TABLE [catalog.][database.]table_name
    DROP TAG [IF EXISTS] <tag_name>;

    例:

    ALTER TABLE tbl DROP TAG t1;

Iceberg テーブルのアクション​

この機能はバージョン 4.0.2 以降でサポートされています。各操作のバージョン要件を確認してください。

これは実験的な機能です。

Doris は ALTER TABLE EXECUTE 構文を使用して、特定の Iceberg テーブルアクションを実行できます。この構文は、テーブルの最適化やスナップショット管理など、さまざまな操作を実行するための統一されたインターフェースを提供します。

ALTER TABLE [catalog.][database.]table_name
EXECUTE <action_name> ("key1" = "value1", "key2" = "value2", ...)
[WHERE <condition>]
  • action_name:実行する操作の名前
  • ("key1" = "value1", ...):キーと値の組で指定する操作関連のパラメータ。パラメータ名は二重引用符で囲む必要があります。
  • [WHERE <condition>]:操作対象のパーティションまたはデータ範囲を指定する任意の WHERE 条件(一部の操作でのみサポート)

cherrypick_snapshot​

cherrypick_snapshot 操作は、指定したスナップショットの変更を現在のテーブル状態にマージし、元のスナップショットを変更・削除せずに新しいスナップショットを作成します。

対応バージョン:4.0.2+

構文:

ALTER TABLE [catalog.][database.]table_name
EXECUTE cherrypick_snapshot ("snapshot_id" = "<snapshot_id>")

パラメータ:

パラメータ型必須説明
snapshot_idLongはいマージするスナップショット ID

戻り値:

cherrypick_snapshot 操作を実行すると、次の 2 カラムを持つ結果セットが返されます。

カラム名型説明
source_snapshot_idBIGINTマージしたスナップショット ID
current_snapshot_idBIGINTマージ操作後に新たに作成され、現在のスナップショットに設定された ID

例:

-- Merge changes from snapshot 123456789 into the current table state
ALTER TABLE iceberg_db.iceberg_table
EXECUTE cherrypick_snapshot ("snapshot_id" = "123456789");

注意事項:

  1. この操作は WHERE 条件に対応していません。
  2. 指定したスナップショットが存在しない場合、操作は失敗します。
  3. マージ操作では新しいスナップショットが作成され、元のスナップショットは削除されません。

expire_snapshots​

expire_snapshots 操作は、Iceberg テーブルから古いスナップショットを削除し、ストレージ領域を解放してメタデータの処理性能を改善します。この操作は Apache Iceberg Spark procedure の仕様に従います。

対応バージョン:4.1.0+

構文:

ALTER TABLE [catalog.][database.]table_name
EXECUTE expire_snapshots ("key1" = "value1", "key2" = "value2", ...)

パラメータ:

パラメータ型必須説明
older_thanStringいいえスナップショットの期限切れを判定する時刻のしきい値。これより古いスナップショットを削除します。ISO 日時形式(例:2024-01-01T00:00:00)またはミリ秒単位のタイムスタンプに対応します。
retain_lastIntegerいいえ保持する祖先スナップショットの数。単独で指定すると、older_than は自動的に現在時刻に設定されます。
snapshot_idsStringいいえ期限切れにする特定のスナップショット ID をカンマ区切りで指定します。
max_concurrent_deletesIntegerいいえ削除操作に使用するスレッドプールのサイズ。
clean_expired_metadataBooleanいいえtrue に設定すると、使用されていないパーティション仕様とスキーマをクリーンアップします。

戻り値:

expire_snapshots 操作を実行すると、次の 6 カラムを持つ結果セットが返されます。

カラム名型説明
deleted_data_files_countBIGINT削除したデータファイルの数
deleted_position_delete_files_countBIGINT削除した Position Delete ファイルの数
deleted_equality_delete_files_countBIGINT削除した Equality Delete ファイルの数
deleted_manifest_files_countBIGINT削除したマニフェストファイルの数
deleted_manifest_lists_countBIGINT削除したマニフェストリストファイルの数
deleted_statistics_files_countBIGINT削除した統計ファイルの数

例:

-- Expire snapshots, keeping only the last 2
ALTER TABLE iceberg_db.iceberg_table
EXECUTE expire_snapshots ("retain_last" = "2");

-- Expire snapshots older than a specific timestamp
ALTER TABLE iceberg_db.iceberg_table
EXECUTE expire_snapshots ("older_than" = "2024-01-01T00:00:00");

-- Expire specific snapshots by ID
ALTER TABLE iceberg_db.iceberg_table
EXECUTE expire_snapshots ("snapshot_ids" = "123456789,987654321");

-- Combine parameters: expire snapshots older than 2024-06-01 but keep at least the last 5
ALTER TABLE iceberg_db.iceberg_table
EXECUTE expire_snapshots ("older_than" = "2024-06-01T00:00:00", "retain_last" = "5");

注意事項:

  1. この操作は WHERE 条件に対応していません。
  2. older_than と retain_last の両方を指定した場合は、両方の条件が適用されます。older_than より古く、かつ直近の retain_last 個のスナップショットに含まれないものだけが削除されます。
  3. snapshot_ids は単独で使用し、特定のスナップショットを削除できます。
  4. この操作はスナップショットと関連するデータファイルを完全に削除します。慎重に使用してください。
  5. 実行前に $snapshots システムテーブルをクエリし、テーブルのスナップショット情報を確認することを推奨します。

fast_forward​

fast_forward 操作は、一方のブランチの現在のスナップショットを、もう一方のブランチの最新スナップショットまで進めます。

対応バージョン:4.0.2+

構文:

ALTER TABLE [catalog.][database.]table_name
EXECUTE fast_forward ("branch" = "<branch_name>", "to" = "<target_branch>")

パラメータ:

パラメータ型必須説明
branchStringはい進めるブランチの名前
toStringはい参照先のブランチ名。branch はこのブランチの最新スナップショットまで進められます。

戻り値:

fast_forward 操作を実行すると、次の 3 カラムを持つ結果セットが返されます。

カラム名型説明
branch_updatedSTRING進められたブランチの名前
previous_refBIGINT操作前にブランチが指していたスナップショット ID(NULL の場合あり)
updated_refBIGINT操作後にブランチが指すスナップショット ID

例:

-- Advance the feature branch to the latest snapshot of the main branch
ALTER TABLE iceberg_db.iceberg_table
EXECUTE fast_forward ("branch" = "feature", "to" = "main");

注意事項:

  1. この操作は WHERE 条件に対応していません。
  2. 指定したブランチが存在しない場合、操作は失敗します。
  3. 進められるのはブランチのみで、タグは対象外です。

publish_changes​

publish_changes 操作は、Write-Audit-Publish(WAP)パターンの「Publish」ステップです。この処理では、特定の wap.id 属性を持つスナップショットを見つけて現在のテーブル状態に追加します。これにより、検証後に「ステージング済み」のデータをアトミックに公開できます。

対応バージョン:4.1.0+

構文:

ALTER TABLE [catalog.][database.]table_name
EXECUTE publish_changes ("wap_id" = "<wap-id>")

パラメータ:

パラメータ型必須説明
wap_idStringはい公開するスナップショットの wap.id

戻り値:

publish_changes 操作を実行すると、次の 2 カラムを持つ結果セットが返されます。

カラム名型説明
previous_snapshot_idBIGINT公開前のスナップショット ID
current_snapshot_idBIGINT公開後の新しいスナップショット ID

例:

ALTER TABLE iceberg_db.iceberg_table
EXECUTE publish_changes ("wap_id" = "branch-123")

注意事項:

  1. この操作は WHERE 条件に対応していません。
  2. 指定した wap.id が存在しない場合、操作は失敗します。

rewrite_data_files​

rewrite_data_files 操作は、Iceberg テーブルのデータファイルを書き換えて小さなファイルを統合し、クエリ性能とストレージ効率を最適化します。これは同期操作です。

対応バージョン:4.0.2+

構文:

ALTER TABLE [catalog.][database.]table_name
EXECUTE rewrite_data_files ("key1" = "value1", "key2" = "value2", ...) [WHERE <condition>]

パラメータ:

パラメータ型デフォルト値説明
target-file-size-bytesLong536870912(512MB)目標ファイルサイズ(バイト単位)。出力ファイルの目標サイズです。
min-file-size-bytesLongtarget-file-size-bytes * 0.75最小ファイルサイズ(バイト単位)。これより小さいファイルは書き換えられます。指定しない場合、目標ファイルサイズの 75% がデフォルトです。
max-file-size-bytesLongtarget-file-size-bytes * 1.8最大ファイルサイズ(バイト単位)。これより大きいファイルは分割されます。指定しない場合、目標ファイルサイズの 180% がデフォルトです。
min-input-filesInteger5書き換えを開始するために必要な入力ファイルの最小数。書き換え対象ファイル数がこのしきい値に達した場合にのみ実行されます。
rewrite-allBooleanfalseファイルサイズに関係なくすべてのファイルを書き換えるかどうか。
max-file-group-size-bytesLong107374182400(100GB)単一のファイルグループの最大サイズ(バイト単位)。一つの書き換えタスクが処理するデータ量を制限します。
delete-file-thresholdIntegerInteger.MAX_VALUE書き換えを開始するために必要な削除ファイルの最小数。
delete-ratio-thresholdDouble0.3書き換えを開始するために必要な削除済みレコードの最小比率(削除済みレコード数 / 総レコード数)。範囲:0.0~1.0。
output-spec-idLong2出力ファイルのパーティション仕様 ID。

戻り値:

rewrite_data_files 操作を実行すると、次の 4 カラムを持つ結果セットが返されます。

カラム名型説明
rewritten_data_files_countINT書き換えられたデータファイルの数
added_data_files_countINT新たに追加されたデータファイルの数
rewritten_bytes_countINT書き換えられたバイト数
removed_delete_files_countBIGINT削除された削除ファイルの数

例:

-- Rewrite data files with default parameters
ALTER TABLE iceberg_db.iceberg_table EXECUTE rewrite_data_files();

-- Specify target file size and minimum input files
ALTER TABLE iceberg_db.iceberg_table
EXECUTE rewrite_data_files (
"target-file-size-bytes" = "134217728",
"min-input-files" = "10"
);

-- Rewrite data in specific partitions using WHERE condition
ALTER TABLE iceberg_db.iceberg_table
EXECUTE rewrite_data_files (
"target-file-size-bytes" = "268435456"
)
WHERE date_col = '2024-01-01';

-- Rewrite all files
ALTER TABLE iceberg_db.iceberg_table
EXECUTE rewrite_data_files (
"rewrite-all" = "true",
"target-file-size-bytes" = "536870912"
);

注意事項:

  1. rewrite_data_files 操作ではデータファイルを読み取って書き換えるため、追加の I/O と計算負荷が発生します。クラスタのリソースを適切に割り当ててください。
  2. 実行前に「データファイルの分布を確認する」の SQL を使用して、書き換えが必要かどうかを評価できます。
  3. WHERE 条件を使用すると、書き換え対象のパーティションやデータ範囲を制限できます。この条件に一致するデータを含まないファイルが除外されるため、書き換えるファイル数とデータ量が減ります。
  4. 実行前に「書き換え対象ファイルの選択ロジック」の SQL を使用して、書き換え対象となるファイルを算出できます。

rewrite_manifests​

rewrite_manifests 操作では、マニフェストファイルを書き換えて Iceberg テーブルのメタデータを最適化し、クエリ性能を高めてメタデータ処理の負荷を減らせます。

大規模な Iceberg テーブルでは、小さなマニフェストファイルが多数あるとクエリ計画の性能に影響するため、この操作でマニフェストファイルを最適化できます。

対応バージョン:4.1.0+

構文:

ALTER TABLE [catalog.][database.]table_name
EXECUTE rewrite_manifests();

パラメータ:

パラメータはありません。

戻り値:

rewrite_manifests 操作を実行すると、次の 2 カラムを持つ結果セットが返されます。

カラム名型説明
rewritten_manifests_countBIGINT書き換えられたファイルの数
total_data_manifests_countBIGINT書き換えられたデータマニフェストファイルの数

例:

ALTER TABLE iceberg_db.iceberg_table
EXECUTE rewrite_manifests();

rollback_to_snapshot​

rollback_to_snapshot 操作は、Iceberg テーブルを指定したスナップショットにロールバックします。

対応バージョン:4.0.2+

構文:

ALTER TABLE [catalog.][database.]table_name
EXECUTE rollback_to_snapshot ("snapshot_id" = "<snapshot_id>")

パラメータ:

パラメータ型必須説明
snapshot_idLongはいロールバック先のスナップショット ID

戻り値:

rollback_to_snapshot 操作を実行すると、次の 2 カラムを持つ結果セットが返されます。

カラム名型説明
previous_snapshot_idBIGINTロールバック前の現在のスナップショット ID
current_snapshot_idBIGINTロールバック後に現在のスナップショットとして設定された ID

例:

-- Roll back to snapshot 987654321
ALTER TABLE iceberg_db.iceberg_table
EXECUTE rollback_to_snapshot ("snapshot_id" = "987654321");

注意事項:

  1. この操作は WHERE 条件に対応していません。
  2. 指定したスナップショットが存在しない場合、操作は失敗します。
  3. 現在のスナップショットがすでに対象のスナップショットである場合、新しいスナップショットを作成せずに終了します。

rollback_to_timestamp​

rollback_to_timestamp 操作は、Iceberg テーブルを指定した時点のスナップショットにロールバックします。

対応バージョン:4.0.2+

構文:

ALTER TABLE [catalog.][database.]table_name
EXECUTE rollback_to_timestamp ("timestamp" = "<timestamp>")

パラメータ:

パラメータ型必須説明
timestampStringはいロールバック先の時点。次の二つの形式に対応します。
1. ISO 日時形式:yyyy-MM-dd HH:mm:ss.SSS(例:2024-01-01 10:30:00.000)
2. ミリ秒単位のタイムスタンプ(例:1704067200000)

戻り値:

rollback_to_timestamp 操作を実行すると、次の 2 カラムを持つ結果セットが返されます。

カラム名型説明
previous_snapshot_idBIGINTロールバック前の現在のスナップショット ID
current_snapshot_idBIGINT指定した時点のスナップショット ID。操作後は現在のスナップショットに設定されます。

例:

-- Roll back to specified point in time (ISO format)
ALTER TABLE iceberg_db.iceberg_table
EXECUTE rollback_to_timestamp ("timestamp" = "2024-01-01 10:30:00.000");

-- Roll back to specified point in time (timestamp format)
ALTER TABLE iceberg_db.iceberg_table
EXECUTE rollback_to_timestamp ("timestamp" = "1704067200000");

注意事項:

  1. この操作は WHERE 条件に対応していません。
  2. timestamp パラメータは ISO 日時形式(yyyy-MM-dd HH:mm:ss.SSS)またはミリ秒単位のタイムスタンプ形式に対応します。
  3. 指定した時点に対応するスナップショットがない場合、操作は失敗します。

set_current_snapshot​

set_current_snapshot 操作は、Iceberg テーブルの現在のスナップショットを、指定したスナップショット ID または参照(ブランチかタグ)に設定します。

対応バージョン:4.0.2+

構文:

ALTER TABLE [catalog.][database.]table_name
EXECUTE set_current_snapshot ("snapshot_id" = "<snapshot_id>" | "ref" = "<ref_name>")

パラメータ:

パラメータ型必須説明
snapshot_idLongいずれか一方現在のスナップショットとして設定するスナップショット ID
refStringいずれか一方現在のスナップショットとして設定する参照名(ブランチまたはタグ)

戻り値:

set_current_snapshot 操作を実行すると、次の 2 カラムを持つ結果セットが返されます。

カラム名型説明
previous_snapshot_idBIGINT操作前の現在のスナップショット ID
current_snapshot_idBIGINT操作後のスナップショット ID(snapshot_id パラメータで指定した値、または ref パラメータから解決した値)

例:

-- Set current snapshot by snapshot ID
ALTER TABLE iceberg_db.iceberg_table
EXECUTE set_current_snapshot ("snapshot_id" = "123456789");

-- Set current snapshot by branch name
ALTER TABLE iceberg_db.iceberg_table
EXECUTE set_current_snapshot ("ref" = "feature_branch");

-- Set current snapshot by tag name
ALTER TABLE iceberg_db.iceberg_table
EXECUTE set_current_snapshot ("ref" = "v1.0");

注意事項:

  1. この操作は WHERE 条件に対応していません。
  2. snapshot_id と ref は同時に指定できません。指定できるのはいずれか一方だけです。
  3. 指定したスナップショット ID または参照が存在しない場合、操作は失敗します。
  4. 現在のスナップショットがすでに対象のスナップショットである場合、新しいスナップショットを作成せずに終了します。

publish_changes​

publish_changes 操作は、WAP(Write-Audit-Publish)モードで、指定した wap.id を持つスナップショットを現在のテーブル状態として公開するために使用します。 指定した wap_id と一致する wap.id を持つスナップショットを特定して現在のテーブルに cherry-pick し、ステージング済みのデータをすべての読み取り操作から参照できるようにします。

構文:

ALTER TABLE [catalog.][database.]table_name
EXECUTE publish_changes("wap_id" = "<wap_id>")

パラメータ:

パラメータ:

パラメータ名型必須説明
wap_idSTRINGはい公開する WAP スナップショット ID

戻り値:

publish_changes を実行すると、次の 2 カラムを持つ結果セットが返されます。

カラム名型説明
previous_snapshot_idSTRING公開操作前の現在のスナップショット ID(存在しない場合は NULL)
current_snapshot_idSTRING公開後に新たに作成され、現在のスナップショットとして設定された ID

例:

-- Publish the snapshot whose WAP ID is test_wap_001
ALTER TABLE iceberg_db.iceberg_table
EXECUTE publish_changes("wap_id" = "test_wap_001");

注意事項:

  1. この操作は WHERE 句にも PARTITION/PARTITIONS 句にも対応していません。
  2. write.wap.enabled = true が設定された Iceberg テーブルで、wap.id による WAP スナップショットが生成されている場合にのみ意味があります。
  3. 指定した wap_id に対応するスナップショットが見つからない場合、操作は失敗してエラーを返します。
  4. 公開後、新しいスナップショットが現在のスナップショットになります。
  5. 公開前にスナップショットが存在しない場合、previous_snapshot_id は NULL になることがあります。

Iceberg テーブルの最適化​

データファイルの分布を確認する​

次の SQL を使用して Iceberg テーブルのデータ分布と削除ファイル数を分析し、rewrite_data_files などの最適化が必要かどうかを判断できます。

  • データファイルのサイズ分布を表示します。小さなファイルが多すぎるかどうかを確認できます。

    SELECT
    CASE
    WHEN file_size_in_bytes BETWEEN 0 AND 8 * 1024 * 1024 THEN '0-8M'
    WHEN file_size_in_bytes BETWEEN 8 * 1024 * 1024 + 1 AND 32 * 1024 * 1024 THEN '8-32M'
    WHEN file_size_in_bytes BETWEEN 32 * 1024 * 1024 + 1 AND 128 * 1024 * 1024 THEN '32-128M'
    WHEN file_size_in_bytes BETWEEN 128 * 1024 * 1024 + 1 AND 512 * 1024 * 1024 THEN '128-512M'
    WHEN file_size_in_bytes > 512 * 1024 * 1024 THEN '> 512M'
    ELSE 'Unknown'
    END AS SizeRange,
    COUNT(*) AS FileNum
    FROM store_sales$data_files
    GROUP BY
    SizeRange;

    +-----------+---------+
    | SizeRange | FileNum |
    +-----------+---------+
    | 0-8M | 8 |
    | 8-32M | 6 |
    +-----------+---------+
  • データファイルと削除ファイルの数を表示します。

    SELECT
    CASE
    WHEN content = 0 THEN 'DataFile'
    WHEN content = 1 THEN 'PositionDeleteFile'
    WHEN content = 2 THEN 'EqualityDeleteFile'
    ELSE 'Unknown'
    END AS ContentType,
    COUNT(*) AS FileNum,
    SUM(file_size_in_bytes) AS SizeInBytes,
    SUM(record_count) AS Records
    FROM
    iceberg_table$files
    GROUP BY
    ContentType;

    +--------------------+---------+-------------+---------+
    | ContentType | FileNum | SizeInBytes | Records |
    +--------------------+---------+-------------+---------+
    | EqualityDeleteFile | 2787 | 1432518 | 27870 |
    | DataFile | 2787 | 4062416 | 38760 |
    | PositionDeleteFile | 11 | 36608 | 10890 |
    +--------------------+---------+-------------+---------+

Dangling Delete​

場合によっては、rewrite_data_files アクションの実行後も、特定の Position Delete への参照がスナップショットメタデータから削除されないことがあります(Dangling Delete)。この状態でメタデータ内の行数情報をそのまま使用すると、結果が不正確になる可能性があります。

そのため、デフォルトでは、COUNT(*) クエリで Position Delete ファイルが見つかった場合、COUNT のプッシュダウン最適化を有効にせず、ファイルを直接読み取って実際の COUNT(*) 結果を取得します。ただし、この方法には時間がかかります。

Dangling Delete の問題がないことを確認できる場合は、Doris のセッション変数 ignore_iceberg_dangling_delete を使用してこの確認を省略できます。この変数のデフォルトは false です。true に設定すると、システムはメタデータ内の行数情報に基づいて COUNT(*) の結果を直接返し、クエリ効率を高めます。

この機能はバージョン 3.1.4 および 4.0.3 以降でサポートされています。

付録​

rewrite_data_files のファイル選択方法​

このセクションでは、書き換え対象ファイルを選択するロジックを説明します。次の SQL クエリを使用すると、システムテーブルの情報に基づいて、どのファイルが書き換え対象になるかを分析できます。実際の書き換え操作を実行する前に、その動作を確認して問題を調査するのに役立ちます。

書き換え操作では、二段階のフィルタリングとグループ化を使用します。

  1. 第 1 段階:ファイル単位のフィルタリング

    まずファイル単位の条件でフィルタリングします。次のいずれかの条件を満たすファイルだけが、書き換え候補になります。

    1. ファイルサイズが範囲外:ファイルが min-file-size-bytes より小さい、または max-file-size-bytes より大きい。
    2. 削除ファイルが多すぎる:関連する削除ファイルの数 >= delete-file-threshold。
    3. 削除率が高い:削除済みレコードの比率 >= delete-ratio-threshold。

    削除ファイルに関する条件の注記: 削除ファイルに関する条件(delete-file-threshold と delete-ratio-threshold)は、書き換え対象ファイルの選択に影響しますが、システムテーブルに対する SQL クエリでは正確に計算できません。現在のシステムテーブルの情報だけでは、削除ファイルの影響を受けるデータファイルを正確に特定できないためです。削除ファイルは特定のデータファイルだけに影響する場合があり(特に Position Delete ファイル)、削除ファイルとデータファイルの関連付けには、現在のシステムテーブルにはない詳細なメタデータが必要です。実際の書き換え操作では、システムテーブルで公開されない詳細なメタデータに基づいてこれらの条件を評価します。

  2. 第 2 段階:BinPack によるグループ化とグループ単位のフィルタリング

    ファイル単位のフィルタリング後、ファイルをパーティションごとに分けます。次に、各パーティション内でファイルサイズと max-file-group-size-bytes に基づく BinPack アルゴリズムを使用してファイルをグループ化します。BinPack アルゴリズムは、書き換え操作を最適化するためにファイルを効率よくグループにまとめます。

    グループ化後、グループ単位の条件でファイルグループをフィルタリングします。次のいずれかを満たすグループが書き換えられます。

    1. 入力ファイルが十分にある:グループ内のファイル数 > 1、かつファイル数 >= min-input-files。
    2. データ量が十分にある:グループ内のファイル数 > 1、かつ合計サイズ > target-file-size-bytes。
    3. データ量が多すぎる:グループの合計サイズ > max-file-group-size-bytes。
    4. 削除ファイルに関する問題があるファイルを含む:グループ内の少なくとも一つのファイルで、削除ファイルが多すぎるか削除率が高い。

    BinPack によるグループ化の注記: 各パーティション内のファイルをグループ化する BinPack アルゴリズムは複雑な最適化アルゴリズムであり、システムテーブルに対する SQL クエリでは正確に再現できません。ファイルサイズと max-file-group-size-bytes を考慮してファイルをグループにまとめるため、単純なパーティション単位のグループ化とは結果が異なる場合があります。したがって、以下の SQL クエリで特定できるのはファイル単位の条件を満たすファイルだけであり、最終的に書き換えられるファイルグループを正確に算出することはできません。

クエリ方法の例を示します。

  • クエリ 1:ファイル単位の条件を満たすファイルを特定する

    このクエリは、ファイル単位の条件(ファイルサイズ)を満たし、書き換え候補となるファイルを特定します。

    -- Set parameters (adjust according to your rewrite parameters)
    SET @min_file_size_bytes = 16 * 1024 * 1024; -- 16 MB (default: target-file-size-bytes * 0.75)
    SET @max_file_size_bytes = 768 * 1024 * 1024; -- 768 MB (default: target-file-size-bytes * 1.8)

    SELECT
    file_path,
    `partition`,
    file_size_in_bytes / 1024.0 / 1024.0 AS file_size_mb,
    record_count,
    CASE
    WHEN file_size_in_bytes < @min_file_size_bytes THEN 'Too small'
    WHEN file_size_in_bytes > @max_file_size_bytes THEN 'Too large'
    END AS size_issue
    FROM iceberg_table$data_files
    WHERE file_size_in_bytes < @min_file_size_bytes
    OR file_size_in_bytes > @max_file_size_bytes
    ORDER BY `partition`, file_size_in_bytes DESC;

    出力例:

    +----------------------------------------------------------------------------------------+---------------------------+-------------+--------------+------------+
    | file_path | partition | file_size_mb | record_count | size_issue |
    +----------------------------------------------------------------------------------------+---------------------------+-------------+--------------+------------+
    | s3a://bucket/path/to/table/data/date_col=2024-01-01/00000-0-00000-00000-0.parquet | {"date_col":"2024-01-01"} | 0.00215 | 5 | Too small |
    | s3a://bucket/path/to/table/data/date_col=2024-01-01/00001-0-00001-00001-0.parquet | {"date_col":"2024-01-01"} | 0.00198 | 5 | Too small |
    | s3a://bucket/path/to/table/data/date_col=2024-01-02/00002-0-00002-00002-0.parquet | {"date_col":"2024-01-02"} | 0.00231 | 5 | Too small |
    | s3a://bucket/path/to/table/data/date_col=2024-01-02/00003-0-00003-00003-0.parquet | {"date_col":"2024-01-02"} | 850.23456 | 1250000 | Too large |
    | s3a://bucket/path/to/table/data/date_col=2024-01-03/00004-0-00004-00004-0.parquet | {"date_col":"2024-01-03"} | 0.00245 | 5 | Too small |
    +----------------------------------------------------------------------------------------+---------------------------+-------------+--------------+------------+
    5 rows in set

    注: このクエリで特定できるのは、ファイル単位の条件(ファイルサイズ)を満たすファイルだけです。実際に書き換えられるファイルグループは BinPack のグループ化アルゴリズムに依存し、SQL クエリでは正確に再現できません。このクエリで特定されたファイルが BinPack によって別の形でグループ化されたり、グループ単位の条件によって一部のグループが除外されたりする場合があります。

  • クエリ 2:全体の統計概要

    このクエリは、ファイル単位の条件を満たすファイルに関する全体の統計を示します。

    -- Set parameters (adjust according to your rewrite parameters)
    SET @min_file_size_bytes = 16 * 1024 * 1024;
    SET @max_file_size_bytes = 768 * 1024 * 1024;

    WITH file_analysis AS (
    SELECT
    `partition`,
    file_path,
    file_size_in_bytes,
    record_count,
    (file_size_in_bytes < @min_file_size_bytes OR file_size_in_bytes > @max_file_size_bytes) AS meets_file_level_conditions
    FROM iceberg_table$data_files
    )
    SELECT
    'Total files' AS metric,
    COUNT(*) AS value
    FROM file_analysis
    UNION ALL
    SELECT
    'Files meeting file-level conditions',
    SUM(CASE WHEN meets_file_level_conditions THEN 1 ELSE 0 END)
    FROM file_analysis
    UNION ALL
    SELECT
    'Total size (GB)',
    ROUND(SUM(file_size_in_bytes) / 1024.0 / 1024.0 / 1024.0, 2)
    FROM file_analysis
    UNION ALL
    SELECT
    'Size meeting file-level conditions (GB)',
    ROUND(SUM(CASE WHEN meets_file_level_conditions THEN file_size_in_bytes ELSE 0 END) / 1024.0 / 1024.0 / 1024.0, 2)
    FROM file_analysis
    UNION ALL
    SELECT
    'Percentage meeting file-level conditions (%)',
    ROUND(SUM(CASE WHEN meets_file_level_conditions THEN 1 ELSE 0 END) * 100.0 / COUNT(*), 2)
    FROM file_analysis;

    出力例:

    +----------------------------------------------+--------+
    | metric | value |
    +----------------------------------------------+--------+
    | Total files | 15.00 |
    | Total size (GB) | 2.45 |
    | Files meeting file-level conditions | 12.00 |
    | Size meeting file-level conditions (GB) | 1.85 |
    | Percentage meeting file-level conditions (%) | 80.00 |
    +----------------------------------------------+--------+
    5 rows in set

    注意事項:

    • 例中の iceberg_table を実際のテーブル名に置き換えてください。
    • 実際の書き換えパラメータに合わせて、パラメータ値(@min_file_size_bytes、@max_file_size_bytes)を調整してください。
    • 上に示したデフォルト値は、書き換えパラメータのデフォルト(min-file-size-bytes = target-file-size-bytes * 0.75、max-file-size-bytes = target-file-size-bytes * 1.8)に対応します。
  • スナップショットとブランチの関係を確認する:

    SELECT
    refs_data.snapshot_id,
    snapshots.committed_at,
    snapshots.operation,
    ARRAY_SORT(refs_data.refs)
    FROM (
    SELECT
    snapshot_id,
    ARRAY_AGG(CONCAT(type, ':', name)) AS refs
    FROM
    iceberg_table$refs
    GROUP BY
    snapshot_id
    ) AS refs_data
    JOIN (
    SELECT
    snapshot_id,
    committed_at,
    operation
    FROM
    iceberg_table$snapshots
    ) AS snapshots
    ON refs_data.snapshot_id = snapshots.snapshot_id
    ORDER BY
    snapshots.committed_at;

    +---------------------+----------------------------+-----------+-------------------------------------+
    | snapshot_id | committed_at | operation | ARRAY_SORT(refs_data.refs) |
    +---------------------+----------------------------+-----------+-------------------------------------+
    | 8272911997874079853 | 2025-07-10 15:27:07.177000 | append | ["BRANCH:b1", "TAG:t1"] |
    | 1325777059626757917 | 2025-07-10 15:27:07.530000 | append | ["BRANCH:b2", "TAG:t2"] |
    | 76492482642020578 | 2025-07-10 15:27:07.865000 | append | ["BRANCH:b3", "TAG:t3"] |
    | 1788715857849070138 | 2025-07-12 04:15:19.626000 | append | ["BRANCH:main", "TAG:t4", "TAG:t5"] |
    +---------------------+----------------------------+-----------+-------------------------------------+
On This Page