メインコンテンツまでスキップ
バージョン: 4.x

Iceberg Catalog

Dorisは、様々なメタデータサービスを通じてIcebergテーブルデータへのアクセスをサポートしています。データの読み取りに加え、DorisはIcebergテーブルへの書き込みもサポートしており、INSERT、INSERT OVERWRITE、UPDATE、DELETE、およびMERGE INTOが含まれます。

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をメタデータサービスとして使用します。

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

  • <warehouse>

    Icebergのwarehouseパス。このパラメータは<iceberg_catalog_type>hadoopの場合に指定する必要があります。

    warehouseパスはDatabaseパスの上位レベルを指す必要があります。例えば、テーブルパスがs3://bucket/path/to/db1/table1の場合、warehouses3://bucket/path/to/にする必要があります。

  • {MetaStoreProperties}

    MetaStorePropertiesセクションは、Metastoreメタデータサービスの接続と認証情報を入力するためのものです。[Supported Metadata Services]のセクションを参照してください。

  • {StorageProperties}

    StoragePropertiesセクションは、ストレージシステムに関連する接続と認証情報を入力するためのものです。[Supported Storage Systems]のセクションを参照してください。

  • {IcebergProperties}

    IcebergPropertiesセクションは、Iceberg Catalog固有のパラメータを記入するために使用されます。

    • list-all-tables

      Hive Metastoreをメタデータサービスとして使用するIceberg Catalog用。デフォルトはtrueです。デフォルトでは、SHOW TABLES操作は現在のDatabaseのすべてのタイプのテーブルをリストします(Hive MetastoreにはIcebergタイプ以外のテーブルが保存されている場合があります)。このアプローチは最高のパフォーマンスを持ちます。

      falseに設定した場合、Dorisは各テーブルのタイプを一つずつチェックし、Icebergタイプのテーブルのみを返します。このモードは、テーブルが多数ある場合にパフォーマンスが悪くなります。

  • {CommonProperties}

    CommonPropertiesセクションは、一般的なプロパティを入力するためのものです。共通プロパティの詳細については、Catalog Overviewを参照してください。

メタデータキャッシュ

外部データソースへのアクセスパフォーマンスを向上させるため、Apache DorisはIcebergメタデータをキャッシュします。メタデータには、テーブル構造(Schema)、テーブルオブジェクト、ビューオブジェクト、manifestの詳細が含まれます。

ヒント

Doris 4.1.x以前のバージョンでは、メタデータキャッシュは主にFE設定項目によってグローバルに制御されていました。詳細については、Metadata Cacheを参照してください。 Doris 4.1.x以降では、Iceberg Catalogの外部メタデータキャッシュは統一されたmeta.cache.*キーを使用して設定されます。

キャッシュプロパティ設定 (4.1.x+)

各エンジンのキャッシュエントリは統一された設定キー形式を使用します:meta.cache.<engine>.<entry>.{enable,ttl-second,capacity}

プロパティ意味
enabletrue/falseこのキャッシュモジュールを有効にするかどうか。
ttl-second6000-10はキャッシュを無効にする(即座に有効になり、最新データを確認するために使用可能);-1は期限切れなし;その他の正の整数はアクセス時刻を基準としたTTL秒数を意味します。
capacity10000最大キャッシュエントリ数(カウント単位)。0は無効を意味します。

有効ロジック: モジュールキャッシュはenable=truettl-second != 0capacity > 0の場合のみ有効になります。

キャッシュモジュール

Iceberg Catalogには以下のキャッシュモジュールが含まれます:

モジュール (<entry>)プロパティキープレフィックスキャッシュ内容と影響
schemameta.cache.iceberg.schema.テーブル構造をキャッシュ。影響:テーブル列情報の可視性。無効にした場合、各クエリで最新のSchemaが取得されます。
tablemeta.cache.iceberg.table.Icebergテーブルメタデータオブジェクトをキャッシュ。影響:Catalog/Metastoreとのラウンドトリップを削減。
viewmeta.cache.iceberg.view.Iceberg Viewメタデータオブジェクトをキャッシュ。
manifestmeta.cache.iceberg.manifest.manifestの詳細をキャッシュ。影響:重複するmanifestアクセスのオーバーヘッドを削減。注意:このモジュールはデフォルトで無効になっており、手動で有効にする必要があります。

レガシーパラメータマッピングと変換

バージョン4.1.x以降では、統一キーを推奨します。以下は、レガシーCatalogプロパティと4.1.x+統一キーとのマッピングです:

レガシープロパティキー4.1.x+統一キー説明
schema.cache.ttl-secondmeta.cache.iceberg.schema.ttl-secondテーブル構造キャッシュの有効期限

ベストプラクティス

  • 最新データへのリアルタイムアクセス:各クエリでIcebergテーブルの最新スナップショットやスキーマ変更を確認したい場合は、schematablettl-second0に設定できます。

    -- Disable table object cache to detect snapshot changes
    ALTER CATALOG iceberg_ctl SET PROPERTIES ("meta.cache.iceberg.table.ttl-second" = "0");
  • パフォーマンス最適化:

    • マニフェストキャッシュを有効にすることで、大きなテーブルに対するクエリプランニングを大幅に高速化できます:

      ALTER CATALOG iceberg_ctl SET PROPERTIES (
      "meta.cache.iceberg.manifest.enable" = "true",
      "meta.cache.iceberg.manifest.ttl-second" = "600"
      );
  • Iceberg CatalogにおけるALTER CATALOG ... SET PROPERTIESによる変更はホットリロードをサポートしています。

可観測性

キャッシュメトリクスはinformation_schema.catalog_meta_cache_statisticsシステムテーブルから確認できます:

SELECT catalog_name, engine_name, entry_name,
effective_enabled, ttl_second, capacity,
estimated_size, hit_rate, load_failure_count, last_error
FROM information_schema.catalog_meta_cache_statistics
WHERE catalog_name = 'iceberg_ctl' AND engine_name = 'iceberg'
ORDER BY entry_name;

このシステムテーブルのドキュメントを参照してください:catalog_meta_cache_statistics。

サポートされている Iceberg バージョン

Doris VersionIceberg SDK Version
2.11.6.1
3.01.6.1
3.11.9.1
4.01.9.1

サポートされている Iceberg フォーマット

  • Iceberg V1/V2 フォーマットをサポートします。
  • Position Delete と Equality Delete の読み取りをサポートします。
  • Deletion Vector の読み取りをサポートします(4.1.0以降)。

サポートされているメタデータサービス

注意:異なるDorisバージョンでサポートされているサービスタイプとパラメータは若干異なります。[Examples]セクションを参照してください。

Iceberg Catalog 機能サポートマトリックス

Metadata ServiceTable QueryView QueryDDL OperationsData WritebackSystem Tables (3.1+以降でサポート)
Hive MetaStore
AWS Glue
Aliyun DLF
Iceberg Rest Catalogサービスプロバイダーに依存サービスプロバイダーに依存サービスプロバイダーに依存
FileSystem

サポートされているストレージシステム

注意:異なるDorisバージョンでサポートされているサービスタイプとパラメータは若干異なります。[Examples]セクションを参照してください。

サポートされているデータフォーマット

カラム型マッピング

Iceberg TypeDoris TypeComment
booleanboolean
integerint
longbigint
floatfloat
doubledouble
decimal(P, S)decimal(P, S)
datedate
timestamp (Timestamp without timezone)datetime(6)精度6のdatetimeにマッピング
timestamptz (Timestamp with timezone)datetime(6)/timestamptz(6)精度6のdatetimeにマッピング。enable.mapping.timestamp_tzプロパティ(バージョン4.0.3以降でサポート)がマッピング動作を制御します。デフォルトではfalseに設定されており、この場合はdatetime型にマッピングされます。trueに設定すると、timestamptz型にマッピングされます。
fixed(N)char(N)
stringstring
binarystring/varbinaryCatalogのenable.mapping.varbinaryプロパティによって制御されます(4.0.2以降でサポート)。デフォルトはfalsestringにマッピングされ、trueの場合はvarbinary型にマッピングされます。
uuidstring/varbinaryversion < 4.0.2ではstring型にマッピング、version == 4.0.2ではvarbinary型にマッピング。version > 4.0.2では、propertiesのenable.mapping.varbinaryプロパティによって制御されます。デフォルトはfalsestringにマッピングされます。
structstruct(バージョン2.1.3以降でサポート)
mapmap(バージョン2.1.3以降でサポート)
listarray
otherUNSUPPORTED

注意:

Dorisは現在、タイムゾーン付きのTimestamp型をサポートしていません。すべてのtimestamptimestamptzは統一的にdatetime(N)型にマッピングされます。ただし、読み書き時には、Dorisは実際のソース型に基づいてタイムゾーンを正しく処理します。例えば、SET time_zone=<tz>でタイムゾーンを指定した後、timestamptzカラムの読み書き結果に影響します。

DESCRIBE table_name文のExtraカラムで、ソース型にタイムゾーン情報があるかどうかを確認できます。WITH_TIMEZONEと表示されている場合、ソース型がタイムゾーン対応型であることを示します。(3.1.0以降でサポート)。

バージョン4.0.3以降でサポートされており、timestamptz(timestamp with time zone)はDorisのtimestamptz型にマッピングできます。

ネームスペースマッピング

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

      ┌─────────┐             
│ Catalog │
└────┬────┘

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

┌──────┴───────┐
┌────▼───┐ ┌────▼───┐
│ Table2 │ │ Table3 │
└────────┘ └────────┘

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

上記の例では、テーブルは以下のロジックに従ってDorisメタデータにマッピングされます:

CatalogDatabaseTable
CatalogNS1Table1
CatalogNS2.NS3Table2
CatalogNS2.NS3Table3

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

Hive Metastore

3.1+ Version

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 Version

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ディレクトリにcredentialsファイルを生成する必要があります。

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

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+ バージョン

S3でメタデータストレージとしてPostgreSQLを使用する

CREATE CATALOG iceberg_jdbc_postgresql PROPERTIES (
'type' = 'iceberg',
'iceberg.catalog.type' = 'jdbc',
'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+ Version

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 Integrationのドキュメントを参照してください。

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 Integration のドキュメントを参照してください。

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>'
);

クエリ操作

基本クエリ

-- 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;

Time Travel

Iceberg テーブルの特定のスナップショットを読み取ることができます。

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

iceberg_meta() テーブル関数を使用して、Iceberg テーブルの特定のスナップショットをクエリできます:

SELECT * FROM iceberg_meta(
'table' = 'iceberg_ctl.iceberg_db.iceberg_tbl',
'query_type' = '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 OFFOR 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;

Branch と Tag

3.1.0以降。

branchとtagの作成、削除、管理については、[Managing Branch & Tag]セクションを参照してください。

Icebergテーブルの特定のbranchとtagの読み取りがサポートされています。

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 はパラメータがタイムスタンプなのか Branch/Tag 名なのかを自動的に判定します。

View

3.1.0 以降

Iceberg view のクエリをサポートしています。View クエリは通常のテーブルクエリと同じように動作します。以下の点にご注意ください:

  • hms タイプの Iceberg Catalog のみがサポートされています。
  • view 定義 SQL は Doris SQL dialect と互換性がある必要があります。そうでなければ解析エラーが発生します。(Dialect 変換機能は将来のバージョンで提供される予定です)。

Iceberg V3 Hidden Columns (Row Lineage)

ヒント

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

Doris は Iceberg V3 テーブルの Row Lineage hidden column のクエリをサポートしています。Iceberg V3 では、データ変更レコードを追跡するために使用される row lineage データを含む system hidden column が導入されています。これは増分同期やデータ監査に非常に適しています:

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

hidden column をクエリする方法:

デフォルトでは、DESCSELECT * を使用した際に hidden column は表示されません。カラム名を直接指定することで明示的にクエリできます:

SELECT id, _row_id, _last_updated_sequence_number FROM iceberg_tbl;

また、セッション変数 show_hidden_columns を有効にすることで、通常の表示(DESCSELECT * など)で非表示の列を表示することもできます:

SET show_hidden_columns = true;
DESC iceberg_tbl;

注意:

  1. これらの行レベルパラメータを生成するには、Icebergテーブルのformat version(format-version)を3に設定する必要があります。V1およびV2形式のテーブルで行系譜列をクエリすると、エラーが発生する可能性があります。
  2. 隠し列はシステムによって維持されます。ユーザーはINSERTなどの書き込み文を使用する際に、_row_idまたは_last_updated_sequence_number列を明示的に指定したり書き込んだりすることはできません。

System Tables

Since 3.1.0

DorisはIceberg system tablesのクエリをサポートしており、テーブルに関するメタデータ情報を取得できます。system tablesを使用して、スナップショット履歴、manifestファイル、データファイル、パーティション、その他のメタデータを表示できます。

Icebergテーブルのメタデータにアクセスするには、テーブル名の後に$記号とsystem table名を追加します:

SELECT * FROM iceberg_table$system_table_name;

例えば、テーブルの履歴を表示するには、次を実行できます:

SELECT * FROM iceberg_table$history;

all_manifests システムテーブルはバージョン 4.0.4 から対応しています。

position_deletes システムテーブルはまだサポートされておらず、将来のバージョンでのサポートが予定されています。

entries

テーブルの現在のスナップショットのすべてのmanifestエントリを表示します:

all_entriesentries は類似していますが、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 |
+----------------------------+---------------------+---------------------+---------------------+

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から対応しています

テーブルの全ての有効なスナップショットのmanifestファイル情報を表示します:

all_manifestsmanifestsは同じ構造を持ちます。違いは、all_manifestsは全ての有効なスナップショットからのmanifestファイルを含む一方、manifestsは現在のスナップショットからのmanifestファイルのみを含む点です。

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 以降、static partition(またはhybrid)へのデータ書き込みをサポート:

-- 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の行は新しいnameageで更新されます。
  • 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;
  • not matchedのみでinsertを実行する:

    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. 上記の3つの操作(DELETEUPDATEMERGE INTO)はすべて、Icebergテーブルのフォーマットバージョン(format-version)が2以上である必要があります。V1フォーマットテーブルでこれらの操作を試行すると、エラーmust have format version 2 or higher for position deletesが発生します。V3フォーマットテーブルで実行される場合、システムは元のPosition Deleteデータを置き換えるためにPuffin形式のDeletion Vectorsを使用するだけでなく、コンテンツの更新が含まれる場合は、書き込まれたレコードの系譜ライフサイクル属性(_last_updated_sequence_number)も自動的に調整します。
  2. これらの操作はParquetとORCの両方のファイル形式をサポートしています。
  3. 並行書き込みシナリオでは、Icebergは楽観的並行制御メカニズムを提供します。書き込み競合が発生した場合、操作はトランザクション競合例外をスローすることがあります。
  4. UPDATE操作は、単独でもMERGE INTO内でも、age = age * 2 + 1name = concat(name, '-modified')などの式や関数の使用をサポートしています。
  5. これらの操作はパーティション化されたテーブルと非パーティション化されたテーブルの両方に適用されます。

関連パラメータ

  • 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非パーティション化テーブルでscaling-writeを開始するためのデータしきい値。table_sink_non_partition_write_scaling_data_processed_thresholdのデータが追加されるごとに新しいwriter(インスタンス)が使用されます。このメカニズムはデータ量に基づいてwriterの数を調整し、スループットを向上させながらリソースを節約し、少量のデータに対してファイル数を最小化します。
    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文を使用して目的のカタログに切り替え、CREATE DATABASEコマンドを実行できます:

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

完全修飾名を使用してデータベースを作成することや、ロケーションを指定することも可能です(現在、HMS-typeカタログのみがロケーションの指定をサポートしています)。例えば:

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 Databaseの場合、データベース自体を削除する前に、まずデータベース内のすべてのテーブルを削除する必要があります。そうしないと、エラーが発生します。

テーブルの作成と削除

  • テーブルの作成

    Dorisは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テーブルの作成文を表示できます。パーティション関数の詳細については、Partitioning セクションを参照してください。

  • テーブルの削除

    DROP TABLE 文を使用してIcebergテーブルを削除できます。テーブルを削除すると、パーティションデータを含むそのデータも削除されます。

    例:

    DROP TABLE [IF EXISTS] iceberg_tbl;
  • Column Type Mapping

    Column Type Mapping セクションを参照してください。

  • パーティショニング

    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テーブルが他のシステムによって作成された場合、timestamptimestamp_ntzタイプは両方ともDoris Datetimeタイプにマップされますが、書き込み時には実際のタイプに基づいてタイムゾーンの処理が必要かどうかを判定します。

    • ORC

  • 圧縮形式

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

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

  • ストレージメディア

    • HDFS

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

Schema Change

3.1.0から、DorisはIcebergテーブルのスキーマ変更をサポートし、ALTER TABLE文を使用して変更できます。

サポートされるスキーマ変更操作には以下が含まれます:

  • 列名の変更

    RENAME COLUMN句を使用して列名を変更します。ネストされたタイプ内の列名変更はサポートされていません。

    ALTER TABLE iceberg_table RENAME COLUMN old_col_name TO new_col_name;
  • 列の追加

    新しい列を追加するにはADD COLUMNを使用します。ネストされた型への新しい列の追加はサポートされていません。

    新しい列を追加する際、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

    列を削除するにはDROP COLUMNを使用します。ネストされた型内の列の削除はサポートされていません。

    ALTER TABLE iceberg_table DROP COLUMN col_name;
  • カラムの変更

    MODIFY COLUMNステートメントを使用して、型、nullable、デフォルト値、コメント、カラム位置を含むカラム属性を変更します。

    バージョン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) where m > n

    複合型の制約:

    • すべての新しいネストされたフィールドはnullableである必要があります。
    • optionalからrequiredに変更することはできません。
    • 複合型のデフォルト値は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, ...);

Partition Evolution

バージョン4.0.2から、DorisはIcebergテーブルに対してALTER文を通じたPartition Evolutionをサポートしています。

サポートされているパーティション変換は以下の通りです:

TransformSyntaxExample
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;

ブランチとタグの管理

Since 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;
  • Drop Branch

    構文:

    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;
  • Drop Tag

    構文:

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

例:

ALTER TABLE tbl DROP TAG t1;

Iceberg Table Actions

この機能はバージョン4.0.2から対応しています。各操作の具体的なバージョン要件については確認してください。

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

DorisはIcebergテーブルの特定のアクションをALTER TABLE EXECUTE構文を通じて実行することをサポートしています。この構文は、テーブル最適化やスナップショット管理などの様々な操作を実行するための統一インターフェースを提供します。

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>")

パラメータ:

ParameterTypeRequiredDescription
snapshot_idLongYesマージするスナップショットID

戻り値:

cherrypick_snapshot オペレーションを実行すると、以下の2つの列を持つ結果セットが返されます:

Column NameTypeDescription
source_snapshot_idBIGINTマージされたスナップショットID
current_snapshot_idBIGINTマージオペレーション後に新しく作成され、currentに設定されたスナップショット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プロシージャ仕様に従います。

サポートバージョン: 4.1.0+

構文:

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

パラメータ:

パラメータ必須説明
older_thanStringいいえスナップショット削除の閾値となるタイムスタンプ。これより古いスナップショットが削除されます。ISO datetime形式(例: 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削除されたポジション削除ファイルの数
deleted_equality_delete_files_countBIGINT削除されたイコール削除ファイルの数
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_thanretain_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>")

パラメータ:

ParameterTypeRequiredDescription
branchStringYes進めるブランチの名前
toStringYesターゲットブランチ名; branch はこのブランチの最新スナップショットまで進められます

戻り値:

fast_forward 操作を実行すると、以下の3つの列を持つ結果セットが返されます:

Column NameTypeDescription
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. 指定されたbranchが存在しない場合、操作は失敗します
  3. branchのみ進めることができ、tagは対象外です

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>")

パラメータ:

ParameterTypeRequiredDescription
wap_idStringYes公開するスナップショットの wap.id

戻り値:

publish_changes オペレーションを実行すると、以下の2つの列を持つ結果セットが返されます:

Column NameTypeDescription
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. 実行前に、View Data File DistributionセクションのSQLを使用して、書き換えが必要かどうかを評価することができます
  3. WHERE条件を使用して、書き換え対象のパーティションやデータ範囲を制限できます。この条件により、WHERE条件に一致するデータを含まないファイルが除外され、書き換えるファイル数とデータ量が削減されます
  4. 実行前に、Rewrite File Selection Logicセクションの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>")

パラメータ:

ParameterTypeRequiredDescription
snapshot_idLongYesロールバック先のスナップショットID

戻り値:

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

Column NameTypeDescription
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>")

パラメータ:

ParameterTypeRequiredDescription
timestampStringYesロールバック先の時点。2つのフォーマットをサポート:
1. ISO datetime フォーマット: yyyy-MM-dd HH:mm:ss.SSS (例: 2024-01-01 10:30:00.000)
2. ミリ秒タイムスタンプ (例: 1704067200000)

戻り値:

rollback_to_timestamp 操作を実行すると、以下の2列を持つ結果セットが返されます:

Column NameTypeDescription
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 datetime形式(yyyy-MM-dd HH:mm:ss.SSS)またはミリ秒timestamp形式をサポートします
  3. 指定された時点に対応するsnapshotが存在しない場合、操作は失敗します

set_current_snapshot

set_current_snapshot操作は、Icebergテーブルの現在のsnapshotを指定されたsnapshot IDまたはreference(branchまたはtag)に設定します。

サポートバージョン: 4.0.2+

構文:

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

パラメータ:

ParameterTypeRequiredDescription
snapshot_idLongいずれか一つ現在として設定するスナップショットID
refStringいずれか一つ現在として設定する参照名(ブランチまたはタグ)

戻り値:

set_current_snapshotオペレーションを実行すると、以下の2つの列を持つ結果セットが返されます:

Column NameTypeDescription
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_idSTRINGYes公開する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への参照がSnapshotメタデータから削除されていないことがあります(Dangling Delete)。この状況で、メタデータの行番号情報を直接使用すると、結果が正しくない場合があります。

そのため、デフォルトではCOUNT(*)クエリにおいて、Position Deleteファイルが見つかった場合、COUNT pushdown最適化は有効になりません。代わりに、ファイルを直接読み取って実際のCOUNT(*)結果を取得します。しかし、この方法は時間がかかります。

ユーザーがDangling Deleteの問題がないことを保証できる場合、Dorisセッション変数ignore_iceberg_dangling_deleteを使用してこのチェックをスキップできます。この変数はデフォルトでfalseです。trueに設定すると、システムはメタデータの行数情報に基づいてCOUNT(*)結果を直接返し、クエリ効率を向上させます。

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

付録

rewrite_data_filesファイル選択ストラテジー

このセクションを確認して、書き換えるファイルを選択するロジックを理解してください。また、以下のSQLクエリを使用して、システムテーブル情報に基づいてどのファイルが書き換えられるかを分析できます。これにより、実際の書き換え操作を実行する前に、書き換え動作をデバッグし理解することができます。

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

  1. ステージ1:ファイルレベルのフィルタリング

    まず、ファイルレベルの条件に基づいてファイルがフィルタリングされます。以下の条件の少なくとも1つを満たすファイルのみが書き換えの対象として考慮されます:

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

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

  2. ステージ2:BinPackグループ化とグループレベルのフィルタリング

    ファイルレベルのフィルタリング後、ファイルはパーティション別にグループ化され、その後各パーティション内で、ファイルサイズとmax-file-group-size-bytesに基づいてBinPackアルゴリズムを使用してファイルがグループ化されます。BinPackアルゴリズムは、書き換え操作を最適化するために、ファイルを賢くグループにパックします。

    グループ化後、ファイルグループはグループレベルの条件に基づいてフィルタリングされます。ファイルグループは、以下の条件の少なくとも1つを満たす場合に書き換えられます:

    1. 十分な入力ファイル:グループ内のファイル数 > 1 かつ ファイル数 >= min-input-files
    2. 十分なコンテンツ:グループ内のファイル数 > 1 かつ 総サイズ > target-file-size-bytes
    3. コンテンツが多すぎる:グループの総サイズ > max-file-group-size-bytes
    4. 削除ファイルの問題があるファイルを含む:グループ内の少なくとも1つのファイルが削除ファイルが多すぎるか削除比率が高い。

    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

注意: このクエリは、ファイルレベルの条件(ファイルサイズ)を満たすファイルのみを特定できます。実際に書き換えられるファイルグループは、SQLクエリでは正確にシミュレートできないBinPackグループ化アルゴリズムに依存します。このクエリで特定されたファイルは、BinPackアルゴリズムによって異なる方法でグループ化される可能性があり、一部のグループはグループレベルの条件に基づいてフィルタリングされる場合があります。

  • Query 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を実際のテーブル名に置き換えてください

  • 実際のrewriteパラメータに応じてパラメータ値(@min_file_size_bytes@max_file_size_bytes)を調整してください

  • 上記に示されているデフォルト値は、デフォルトのrewriteパラメータに対応しています(min-file-size-bytes = target-file-size-bytes * 0.75、max-file-size-bytes = target-file-size-bytes * 1.8)

  • snapshotとbranchの関係を表示:

    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"] |
    +---------------------+----------------------------+-----------+-------------------------------------+
このページでは