Zum Inhalt springen

Iceberg-Erweiterung

Die iceberg-Erweiterung implementiert die Unterstützung für das offene Tabellenformat Apache Iceberg. Es gibt zwei Wege, mit Iceberg in DuckDB zu arbeiten:

  • Einzelne Tabellen werden direkt aus dem Speicher gelesen, indem auf die Metadaten einer Tabelle gezeigt wird. Dazu ist kein Katalog nötig, und der Zugriff ist schreibgeschützt.
  • Katalogverwaltete Tabellen werden über das Anhängen eines Iceberg REST Catalogs angesprochen. Das schaltet den vollen Funktionsumfang frei, einschließlich Schreiben.

Diese Seite behandelt die Grundlagen beider Wege. Siehe auch:

  • Schreiben nach Iceberg beschreibt die unterstützten Schreiboperationen, Partitionierung und Schemaevolution.
  • Iceberg-Funktionen dokumentiert die von der Erweiterung bereitgestellten Funktionen.
  • Iceberg-Optionen dokumentiert die Scan-Parameter, ATTACH-Optionen, Secret-Optionen und Einstellungen.
  • Kataloge erklärt, wie ein Iceberg REST Catalog angehängt wird, mit Anweisungen für bestimmte Kataloge.
  • Fehlerbehebung listet häufige Probleme und ihre Lösungen auf.

Installation und Laden

Die iceberg-Erweiterung wird beim ersten Einsatz automatisch installiert und geladen. Wenn Sie sie manuell installieren und laden möchten, führen Sie aus:

INSTALL iceberg;
LOAD iceberg;

Die Erweiterung aktualisieren

Die iceberg-Erweiterung erhält oft Updates zwischen DuckDB-Releases. Um sicherzustellen, dass Sie die neueste Version haben, aktualisieren Sie Ihre Erweiterungen:

UPDATE EXTENSIONS;

Iceberg-Tabellen lesen

Einzelne Iceberg-Tabellen können mit der Funktion iceberg_scan direkt aus dem Speicher gelesen werden, ohne einen Katalog anzuhängen. Um die Beispiele zu testen, laden Sie die Datei iceberg_data.zip herunter und entpacken Sie sie.

Einzelne Tabellen abfragen

Verwenden Sie die Funktion iceberg_scan, um eine Iceberg-Tabelle von einem Pfad zu lesen:

SELECT count(*)
FROM iceberg_scan('data/iceberg/lineitem_iceberg', allow_moved_paths = true);
count_star()
51793

Die Option allow_moved_paths stellt sicher, dass eine gewisse Pfadauflösung durchgeführt wird, wodurch verschobene Iceberg-Tabellen gescannt werden können.

Sie können in der Abfrage auch direkt das aktuelle Manifest angeben; das kann vor der Abfrage aus dem Katalog aufgelöst werden. In diesem Beispiel ist die Manifestversion eine UUID. Navigieren Sie dazu ins Verzeichnis data/iceberg und führen Sie aus:

SELECT count(*)
FROM iceberg_scan('lineitem_iceberg/metadata/v1.metadata.json');
count_star()
60175

Die vollständige Liste der von iceberg_scan akzeptierten Parameter finden Sie auf der Seite Iceberg-Optionen.

Aus Objektspeichern lesen

Die iceberg-Erweiterung arbeitet mit der httpfs-Erweiterung oder der azure-Erweiterung zusammen, um auf Iceberg-Tabellen in Objektspeichern wie S3 oder Azure Blob Storage zuzugreifen.

SELECT count(*)
FROM iceberg_scan('s3://bucketname/lineitem_iceberg/metadata/v1.metadata.json');

Auf Iceberg-Metadaten zugreifen

Um auf Iceberg-Metadaten zuzugreifen, können Sie die Funktion iceberg_metadata verwenden:

SELECT *
FROM iceberg_metadata('data/iceberg/lineitem_iceberg', allow_moved_paths = true);
manifest_path manifest_sequence_number manifest_content status content file_path file_format record_count
lineitem_iceberg/metadata/10eaca8a-1e1c-421e-ad6d-b232e5ee23d3-m1.avro 2 DATA ADDED EXISTING lineitem_iceberg/data/00041-414-f3c73457-bbd6-4b92-9c15-17b241171b16-00001.parquet PARQUET 51793
lineitem_iceberg/metadata/10eaca8a-1e1c-421e-ad6d-b232e5ee23d3-m0.avro 2 DATA DELETED EXISTING lineitem_iceberg/data/00000-411-0792dcfe-4e25-4ca3-8ada-175286069a47-00001.parquet PARQUET 60175

Snapshots visualisieren

Um die Snapshots einer Iceberg-Tabelle anzuzeigen, verwenden Sie die Funktion iceberg_snapshots:

SELECT *
FROM iceberg_snapshots('data/iceberg/lineitem_iceberg');
sequence_number snapshot_id timestamp_ms manifest_list
1 3776207205136740581 2023-02-15 15:07:54.504 lineitem_iceberg/metadata/snap-3776207205136740581-1-cf3d0be5-cf70-453d-ad8f-48fdc412e608.avro
2 7635660646343998149 2023-02-15 15:08:14.73 lineitem_iceberg/metadata/snap-7635660646343998149-1-10eaca8a-1e1c-421e-ad6d-b232e5ee23d3.avro

iceberg_snapshots nimmt weder allow_moved_paths, snapshot_from_id noch snapshot_from_timestamp als Parameter entgegen.

Metadatenversionen auswählen

Standardmäßig sucht die iceberg-Erweiterung nach einer Datei version-hint.text, um die passende Metadatenversion zu bestimmen. Das kann überschrieben werden, indem den Funktionen der iceberg-Erweiterung über den Parameter version explizit eine Versionsnummer übergeben wird:

SELECT *
FROM iceberg_snapshots(
'data/iceberg/lineitem_iceberg',
version = '1'
);

Standardmäßig suchen iceberg-Funktionen sowohl nach Dateien v{version}.metadata.json als auch {version}.metadata.json, bzw. nach v{version}.gz.metadata.json und {version}.gz.metadata.json, wenn metadata_compression_codec = 'gzip' angegeben ist. Andere Kompressionscodecs werden nicht unterstützt.

Wenn über den Parameter version eine beliebige Textdatei angegeben wird, wird sie geöffnet und als Version-Hint-Datei behandelt:

SELECT *
FROM iceberg_snapshots(
'data/iceberg/lineitem_iceberg',
version = 'version-hint.txt'
);

Die iceberg-Erweiterung öffnet diese Datei und verwendet den gesamten Inhalt der Datei als angegebene Versionsnummer. Beachten Sie, dass der gesamte Inhalt der Datei version-hint.txt als wörtlicher Versionsname behandelt wird, ohne Kodierung, Escaping oder Trimming. Dazu gehören alle Leerzeichen oder unsicheren Zeichen, die explizit formatiert in Dateinamen der unten beschriebenen Logik übernommen werden.

Arbeiten mit alternativen Metadaten-Namenskonventionen

Die iceberg-Erweiterung kann unterschiedliche Metadaten-Namenskonventionen verarbeiten, indem sie über den Parameter version_name_format als kommagetrennte Liste von Formatzeichenketten angegeben werden. Jede Formatzeichenkette muss zwei Parameter %s enthalten. Der erste ist die Position der Versionsnummer im Metadatendateinamen, der zweite die Position der Dateiendung, die durch metadata_compression_codec vorgegeben wird. Das oben beschriebene Verhalten wird durch den Standardwert "v%s%s.metadata.gz,%s%smetadata.gz bereitgestellt. Wenn Sie eine anders benannte Metadatendatei hätten, z. B. rev-2.metadata.json.gz, kann die Tabelle mit der folgenden Anweisung gelesen werden:

SELECT *
FROM iceberg_snapshots(
'data/iceberg/alternative_metadata_gz_naming',
version = '2',
version_name_format = 'rev-%s.metadata.json%s',
metadata_compression_codec = 'gzip'
);

Metadatenversionen „raten“

Standardmäßig muss entweder eine Tabellenversionsnummer oder eine Datei version-hint.text angegeben werden, damit die iceberg-Erweiterung eine Tabelle lesen kann. Das wird typischerweise von einem externen Datenkatalog bereitgestellt. Falls keines von beiden vorhanden ist, kann die iceberg-Erweiterung versuchen, die neueste Version zu raten, indem ? als Parameter version übergeben wird:

SELECT count(*)
FROM iceberg_scan(
'data/iceberg/lineitem_iceberg_no_hint',
version = '?',
allow_moved_paths = true
);

Als „neueste“ Version gilt der Dateiname, der beim Sortieren der Dateinamen lexikografisch am größten ist. Kollationen werden nicht berücksichtigt. Dieses Verhalten ist standardmäßig nicht aktiviert, da es potenziell ACID-Garantien verletzen kann. Es kann aktiviert werden, indem unsafe_enable_version_guessing auf true gesetzt wird. Wenn das gesetzt ist, versuchen iceberg-Funktionen standardmäßig, die neueste Version zu raten, bevor sie fehlschlagen.

SET unsafe_enable_version_guessing = true;
SELECT count(*)
FROM iceberg_scan(
'data/iceberg/lineitem_iceberg_no_hint',
allow_moved_paths = true
);

Time Travel

Um einen historischen Snapshot einer Tabelle zu lesen, übergeben Sie entweder snapshot_from_id oder snapshot_from_timestamp (die beiden schließen sich gegenseitig aus). Verwenden Sie iceberg_snapshots, um die verfügbaren Snapshots aufzulisten:

-- Read a specific snapshot by id
SELECT count(*)
FROM iceberg_scan('data/iceberg/lineitem_iceberg', snapshot_from_id = 7635660646343998149);
-- Read the snapshot that was current at a given time
SELECT count(*)
FROM iceberg_scan('data/iceberg/lineitem_iceberg', snapshot_from_timestamp = TIMESTAMP '2023-02-15 15:08:00');

Einschränkungen des direkten Lesens

  • Zum Lesen einer Tabelle ist ein Version Hint oder eine explizite version erforderlich, sofern Versionsraten nicht aktiviert ist.
  • Nur gzip-komprimierte Metadaten werden unterstützt (über metadata_compression_codec = 'gzip').

Katalogverwaltete Tabellen

Für vollen Lese- und Schreibzugriff — und um die Katalogfunktionen von Iceberg zu nutzen — hängen Sie einen Iceberg REST Catalog an. Die meisten Kataloge authentifizieren sich mit OAuth2; speichern Sie die Anmeldedaten in einem Secret und hängen Sie den Katalog mit ATTACH ... (TYPE iceberg, ...) an:

CREATE SECRET iceberg_secret (
TYPE iceberg,
CLIENT_ID '⟨admin⟩',
CLIENT_SECRET '⟨password⟩',
OAUTH2_SERVER_URI '⟨https://catalog.example.com/v1/oauth/tokens⟩'
);
ATTACH '⟨warehouse⟩' AS my_catalog (
TYPE iceberg,
SECRET iceberg_secret,
ENDPOINT '⟨https://catalog.example.com⟩'
);

Sobald der Katalog angehängt ist, verhält er sich wie jede andere DuckDB-Datenbank: Referenzieren Sie seine Tabellen als ⟨catalog⟩.⟨schema⟩.⟨table⟩ und fragen Sie sie mit gewöhnlichem SQL ab oder ändern Sie sie.

SHOW ALL TABLES;
SELECT count(*) FROM my_catalog.default.events;
INSERT INTO my_catalog.default.events VALUES (1, 'click', now());

Die Metadatenfunktionen funktionieren auch auf Katalogtabellen, wenn ein vollständig qualifizierter Name übergeben wird, z. B. iceberg_snapshots(my_catalog.default.events).

  • Den vollständigen Satz der Schreiboperationen — Partitionierung, UPDATE, DELETE, MERGE INTO, ALTER TABLE und Tabelleneigenschaften — finden Sie unter Schreiben nach Iceberg.
  • Die katalogspezifische Einrichtung sowie die vollständige Liste der ATTACH-Optionen und Secret-Parameter finden Sie unter Iceberg REST Catalogs.

Time Travel

Auf einem angehängten Katalog erfolgt Time Travel mit der Klausel AT direkt auf der Tabelle:

-- Using a snapshot id
SELECT * FROM my_catalog.default.events AT (VERSION => ⟨snapshot_id⟩);
-- Using a timestamp
SELECT * FROM my_catalog.default.events AT (TIMESTAMP => TIMESTAMP '2025-09-22 12:32:43.217');

Interoperabilität mit DuckLake

Die Funktion iceberg_to_ducklake führt eine reine Metadatenkopie eines angehängten Iceberg-Katalogs in einen DuckLake-Katalog durch, sodass Sie Iceberg-Tabellen so abfragen können, als wären sie DuckLake-Tabellen:

-- With an Iceberg catalog attached as my_catalog
ATTACH 'ducklake:my_ducklake.ducklake' AS my_ducklake;
CALL iceberg_to_ducklake('my_catalog', 'my_ducklake');
-- Skip specific tables
CALL iceberg_to_ducklake('my_catalog', 'my_ducklake', skip_tables := ['table_to_skip']);