🧊

DuckDB から Snowflake Open Catalog(Apache Iceberg)接続検証でハマった話

に公開

はじめに

DuckDB から Snowflake Open Catalog(Iceberg REST Catalog)に接続する方法については、
以下の記事を参考にしました。

https://stable.co.jp/blog/duckdb-snowflake-open-catalog

本記事ではこちらの内容を前提としつつ、
実際に検証している中でハマった認証まわりの挙動を整理します。

結論

  • Snowflake Open Catalog 側で credential vending を有効にしていないと
    SELECT 時にデータアクセスできない
  • DuckDB側で指定したcredential(S3 secret)を使いたい場合は
    ATTACH 時に ACCESS_DELEGATION_MODE 'none' を指定する必要がある

DuckDB × Snowflake Open Catalog の基本構成

DuckDB × Snowflake Open Catalog の基本構成

DuckDBからSnowflake Open Catalogをアタッチ

DuckDB 公式ドキュメント:Iceberg REST Catalogsを元に接続する

CREATE SECRET

CREATE SECRET iceberg_secret (
    TYPE iceberg,
    CLIENT_ID '<client_id>',
    CLIENT_SECRET '<secret>' ,
    OAUTH2_SERVER_URI 'https://<orgname>-<accname>.snowflakecomputing.com/polaris/api/catalog/v1/oauth/tokens'
);

ATTACH

ATTACH 'warehouse' AS iceberg_catalog (
   TYPE iceberg,
   SECRET iceberg_secret,
   ENDPOINT 'https://<orgname>-<accname>.snowflakecomputing.com/polaris/api/catalog'
);

DuckDBからクエリを実行してみる

今回のハマりポイントです。

テーブルの存在は確認できるが、SELECTすると失敗する

SHOW ALL TABLES;
  • テーブル一覧は表示される(OAtuth認証/Catalog接続自体は成功している)

SELECT * FROM iceberg_catalog.DUCKDB_OPENCATALOG_TEST_SCHEMA.TEST_ICEBERGTABLE;

このように、

  • Catalog 上ではテーブルが確認できる
  • SELECT 実行時のみ失敗する

という挙動になります。

解決

原因はDuckDBがmetadata file にアクセスするための S3 credential を受け取れていなかったことでした。
以下解決方法2パターンです。

①:credential vending を有効にする

  • Snowflake Open Catalog 側で credential vending を有効化

②:DuckDBに作成した SECRET を使う場合

ATTACH に ACCESS_DELEGATION_MODE を指定
ATTACH 'warehouse' AS iceberg_catalog (
   TYPE iceberg,
   SECRET iceberg_secret,
   ENDPOINT 'https://<orgname>-<accname>.snowflakecomputing.com/polaris/api/catalog',
   DEFAULT_REGION 'ap-northeast-1',
   ACCESS_DELEGATION_MODE 'none'
);

この場合:

  • DuckDB は Catalog から credential を受け取らない
  • 作成したType S3 secret を使用
  • Snowflake Open Catalog 側で credential vending は不要

なお、ACCESS_DELEGATION_MODE については、
DuckDB v1.4.1 のリリースノートで言及されています。

動作確認

上記適用後、以下の SELECT が正常に実行できることを確認しました。

SELECT * FROM iceberg_catalog.DUCKDB_OPENCATALOG_TEST_SCHEMA.TEST_ICEBERGTABLE;

ハマった理由

① カタログ API 経由の情報取得と、データファイルへのアクセスで必要な認証情報が異なる

  • Snowflake Open Catalog では、テーブル一覧やスキーマ情報などの
    カタログ API 経由の情報取得と、
    Iceberg テーブルの実データ(S3 など)へのアクセスで、必要となる認証情報が異なる
  • 実データへのアクセスに必要なストレージ用の認証情報は、
    Snowflake Open Catalog の credential vending 機能によって提供される
  • credential vending が Snowflake Open Catalog 側で無効になっている場合でも、
    カタログ API だけで完結する処理(例:SHOW TABLES など)は先に成功し、
    SELECT のように実データへアクセスする段階で初めて問題が顕在化するため、原因の切り分けを難しくしていた

② 前提としてiceberg_scan が成功していた

CREATE SECRET s3_secret (
  TYPE S3,
  KEY_ID '.......',
  SECRET '.......'
);

SELECT * FROM iceberg_scan('s3://bucket/path');
  • 作成したS3 secret が使用され、テーブルの内容が確認できたため「S3 認証は問題ない」と誤認してしまった

③ エラーメッセージが認証起因に見えない

  • DuckDB は SELECT 時に Table does not exist を返す
  • 認証エラーや permission error として表示されないため、
    認証が原因だと気づきにくかった

おわりに

今回の検証を通して、DuckDB、Iceberg REST Catalog(Snowflake Open Catalog)、
そして storage(S3)の関係や認証モデルについて、
自分の理解がまだ浅かったことを痛感しました。

本記事の内容は、現時点での自分なりの理解をまとめたものです。
もし誤りや、より良い設定方法などがあれば、
コメント等で教えていただけると嬉しいです

DATUM STUDIO

Discussion