DuckDB 2.0.0 LTS „Cinnamon Teal“: Was das Release bei Serverbetrieb, VARIANT und Migration ändert

Ruhige Schreibtischszene mit Notizbuch, Laptop und Papieren im warmen Seitenlicht
Deine Reaktion:

DuckDB 2.0.0 „Cinnamon Teal“ ist die erste große Feature-Version seit DuckDB 1.0 und bündelt laut Projekt fast 20.000 Commits. Das Release erweitert die eingebettete Datenbank unter anderem um den Quack-Server, asynchrone Ein- und Ausgabe, den Datentyp VARIANT, Trigger und einen Agentenmodus. Gerade weil mehrere dieser Funktionen den Einsatzbereich vergrößern, sollten produktive Installationen Dateiformat, Erweiterungen und parallele Zugriffe vor der Migration prüfen.

Der Vergleich mit der Vorgängerversion ist bewusst gewählt: DuckDB 1.0 war auf Stabilität und Abwärtskompatibilität ausgelegt. Die 2.0 ist vor allem eine Funktionsversion. Die Release Notes bündeln Serverbetrieb, asynchrone I/O, einen eigenständigen VARIANT-Typ, einen Agentenmodus, Trigger und einen austauschbaren SQL-Parser. Was davon im Alltag zählt und wo beim Umstieg Vorsicht angebracht ist, steht im Folgenden.

DuckDB 2.0.0 LTS „Cinnamon Teal“ und die drei parallelen Versionslinien

Der wichtigste organisatorische Punkt zuerst: DuckDB 2.0 ist eine Long-Term-Support-Version, unterstützt mindestens bis Oktober 2027. Die vorherige LTS-Version 1.4 bleibt bis zum 17. November 2026 unterstützt. Zusätzlich hat das Team die Supportphase von 1.5 bis März 2027 verlängert und sie damit faktisch ebenfalls zu einer LTS-Version gemacht.

Das hat praktische Folgen. Wer DuckDB in Produktionspipelines betreibt, kann wählen, auf welcher Linie er bleibt, ohne sofort umzusteigen. Drei gepflegte Linien bedeuten aber auch drei Dokumentationsstände und drei Wahrscheinlichkeiten, dass ein Bugfix zuerst in der neuesten Version landet. Ein Blick in den Release-Kalender lohnt sich, bevor man die Version in einem langfristigen Projekt festschreibt.

Bei den Clients gibt es eine Einschränkung: CLI und Python sind zum Start verfügbar, andere Anbindungen wie Go, R oder Java sowie einige Extensions brauchen wegen zusätzlicher Änderungen und Review-Runden ein paar Tage länger. Wer am Releasetag eine Automatisierung über eine dieser Schnittstellen plant, sollte den Puffer einplanen.

Quack-Protokoll und CONNECT: DuckDB wird zum Server

DuckDB war von Anfang an eine In-Process-Datenbank. Alles lief im selben Prozess wie die Anwendung, ohne Netzwerk, ohne Port, ohne Diensteverwaltung. Mit 1.5.3 im Mai kam das Quack-Protokoll dazu, das zusammen mit der gleichnamigen Extension einen Client-Server-Aufbau erlaubt. Jeder DuckDB-Prozess kann damit seine Datenbanken anderen zur Verfügung stellen.

Die 2.0 liefert eine polierte Fassung dieses Protokolls, mit Verbesserungen bei Leistung und Stabilität. Wichtig für die Handhabung ist der neue CONNECT-Befehl: Er hängt eine entfernte Datenbank an und schaltet die Sitzung in einem Schritt dorthin um. Das funktioniert nicht nur mit Quack, sondern auch mit PostgreSQL und MySQL. Für beide greift zusätzlich ein neuer Remote-Pushdown-Optimizer, der Abfragen auf dem entfernten Server ausführt, statt Tabellen über die Leitung zu ziehen.

Beim Betrieb gilt eine Sicherheitsvorgabe. Der Server hört standardmäßig nur auf localhost. Wer Verbindungen von anderen Rechnern erlauben will, lässt den Server auf der lokalen Schleife und stellt ihn hinter einen Reverse Proxy, der TLS beendet. Die Option allow_other_hostname, die den Server direkt exponiert, ist nur zum Testen gedacht. In der CLI gibt es dafür die Kurzformen -serve und -connect, mit denen sich ein Paar aus Server und Client direkt auf der Kommandozeile hochziehen lässt.

Asynchrone I/O und der VARIANT Typ als erste Bürger

Der zweite Block betrifft das Lesen. DuckDB 2.0 führt asynchrone I/O für Parquet, CSV und das eigene Speicherformat ein. Die I/O-Schicht skaliert jetzt unabhängig von der Abfrageverarbeitung: Sie setzt Lesezugriffe im Hintergrund ab und hält mehrere Anfragen gleichzeitig in der Luft. Statt dass ein einzelner Leser pro Anfrage zum Lager läuft, sind mehrere gleichzeitig unterwegs, während die Verarbeitung weiterläuft.

Spürbar wird das dort, wo die Latenz ohnehin groß ist: bei entfernten Lesezugriffen und bei Objektspeichern wie s3://. Wer schon einmal eine Abfrage auf einem Bucket gestartet hat und zugesehen hat, wie die Netzwerkauslastung zwischen einzelnen Anfragen einbricht, kennt das Problem. Das DuckDB-Team hat den Entwurf in einem eigenen Blogpost beschrieben und dabei den Netzwerkdurchsatz über den Verlauf einer Abfrage mit und ohne asynchrone I/O gegenübergestellt.

Der VARIANT Typ wiederum macht aus dem bisherigen Anhängsel ein vollwertiges Sprachmittel. VARIANT speichert halbstrukturierte, schemafreie Daten wie JSON, behält aber die Leistung der spaltenorientierten Ausführung. Jede Zeile darf anders geformt sein, das Ganze bleibt aber ein Binärformat und kein Text, der bei jeder Abfrage neu geparst werden muss. In 1.5 war VARIANT bereits vorhanden, die 2.0 integriert es vollständig.

Dazu erkennt DuckDB 2.0 die gemeinsame Struktur in den Daten und „shreddert“ sie, zerlegt sie also in spaltenweise gespeicherte Teilstücke. Das verbessert Kompression und Ausführungsgeschwindigkeit. Die Kette läuft durchgängig: von der shredded Ausführung direkt aus dem Speicher über das Lesen und Schreiben von VARIANT in Parquet bis zu einer ganzen Familie von variant_-Funktionen. Für Arbeitslasten mit Embeddings, Telemetrie oder uneinheitlichen API-Antworten ist das der spürbarste Fortschritt dieser Version.

Agentenmodus, neuer PEG-Parser und selbst gehostete Extensions

Ein Detail, das leicht zu übersehen ist: Coding-Agenten wie Claude Code, Codex oder Cursor steuern die DuckDB-CLI zunehmend im Auftrag ihrer Nutzer. Die 2.0-CLI erkennt, wenn sie von einem Agenten gestartet wurde, und schaltet in den Agentenmodus: kompakte Markdown-Tabellen statt breiter Rahmen, klare Hinweise bei abgeschnittenen Ergebnissen, frühes Abbrechen ausufernder Abfragen und Fehler als JSON.

Lang laufende Abfragen melden vor dem Start ihre erwarteten Kosten, damit der Agent entscheiden kann, ob sich das Warten lohnt. In Versuchen auf TPC-H reduzierte der Agentenmodus die Ausgabemenge, die das Modell lesen musste, um 59 Prozent. Für manuelle Tests lässt er sich mit -agent einschalten, mit -no-agent abschalten. Das Ziel ist nicht, Maschinen zu bedienen, sondern die Zahl der Tokens zu senken, die ein Modell durchlesen muss, bevor es die nächste Entscheidung trifft.

DuckDB tauscht außerdem einen Grundbaustein aus. Seit dem ersten Commit 2018 nutzte die Datenbank einen von PostgreSQL abgeleiteten Parser, dessen Grammatik mit YACC/Bison erzeugt wurde. Ein solcher LALR(1)-Parser neigt mit wachsendem Sprachumfang zu shift/reduce– und reduce/reduce-Konflikten, weil schon kleine Ergänzungen bestehende Regeln berühren. Der neue, selbst entwickelte PEG-Parser probiert Alternativen in der Reihenfolge aus, in der sie geschrieben stehen, und macht das Hinzufügen von Syntax damit deutlich risikoärmer. Python vollzog in Version 3.9 denselben Wechsel.

Der neue Parser ist als kompatibel zum alten ausgelegt, Fehlermeldungen kommen jetzt aber mit präziser Quelltextposition. Wer doch einen Unterschied bemerkt, kann über die legacy_parser-Extension mit SET enable_legacy_parser = true; zurückwechseln und ein Issue melden. Ergänzend erscheint eine überarbeitete C-API in Version 2, die Komponenten wie Dateisysteme und Tabellenfunktionen für Extensions öffnet, sowie die Möglichkeit, eigene vertrauenswürdige Extension-Repositories zu betreiben. Ein Repository besteht aus einem Namen, einem URL-Präfix und einem oder mehreren RSA-Public-Keys; beim Anlegen holt DuckDB die Schlüssel und pinnt sie samt SHA-256-Fingerabdruck fest. Die Syntax dieses Features kann sich noch ändern.

Trigger, wachsender SQL-Dialekt und die Core-Extensions

Trigger erwartet man in einer analytischen Datenbank nicht unbedingt. DuckDB 2.0 bringt CREATE TRIGGER mit BEFORE– und AFTER-Varianten, FOR EACH ROW und FOR EACH STATEMENT, Übergangstabellen über REFERENCING OLD/NEW TABLE, mehrere Trigger pro Ereignis, RETURNING auf den auslösenden Tabellen sowie DROP TRIGGER. Der klassische Anwendungsfall sind Audit-Tabellen, in denen ein Trigger festhält, was sich geändert hat.

Der zweite Anwendungsfall ist interessanter: Trigger können materialisierte Sichten inkrementell pflegen. Wer etwa den Altersdurchschnitt je Nationalität in einer Tabelle age_statistics mitführen will, legt einen Trigger für Einfügungen und einen für Löschungen an und speichert Summe und Anzahl neben dem Durchschnitt. Beim Einfügen werden die neuen Zeilen je Nationalität aggregiert und eingemischt, beim Löschen abgezogen. Damit rückt ein Punkt näher, der lange im Abschnitt „Future Work“ der Roadmap stand. Einschränkungen gibt es noch, etwa bei BEFORE ... FOR EACH ROW und UPDATE ... FOR EACH ROW.

Auch der SQL-Dialekt wächst weiter. Die Kurzschreibweise $variable ersetzt an den meisten Stellen getvariable('x'). Datenverändernde CTEs erlauben INSERT, UPDATE, DELETE und COPY als Schritte in einer Pipeline. NEAREST-Joins machen aus einer Top-k-Ähnlichkeitssuche eine Join-Klausel, was Vektor- und Embedding-Arbeitslasten entgegenkommt. Verschachtelte Schemata wie CREATE SCHEMA finance.reports sind möglich, ebenso JSON-Mutationsfunktionen wie json_set oder json_remove, die veränderte Kopien zurückgeben. Dazu kommen SQL-Standard FETCH FIRST, UNNEST in der GROUP BY-Klausel und wohldefinierte Semantik für MERGE und UPDATE ... FROM, wenn mehrere Zeilen passen.

Bei den Core-Extensions nennt das Team DuckLake 1.1 mit neuer Spezifikation und Referenzimplementierung, eine Iceberg-Extension auf dem Weg zur vollständigen Implementierung samt REST-Catalog-Optionen für ATTACH sowie eine Delta-Extension, die Tabellen per CREATE TABLE anlegen kann, inklusive Partitionierung, Zeitreise und besserer VARIANT-Unterstützung. Das ist zu viel für einen einzigen Artikel, dazu sollen eigene Beiträge folgen.

Migration auf DuckDB 2.0: Speicherformat, C++17 und der Zeitplan

Die Liste der brechenden Änderungen ist überschaubar, aber sie hat einen Punkt, der ernst genommen werden sollte. DuckDB-Versionen vor 2.0 können keine Datenbankdateien lesen, die von DuckDB 2.0 erzeugt wurden. Umgekehrt liest und schreibt die 2.0 bestehende Dateien weiter, und diese bleiben für ältere Versionen lesbar. Betroffen sind also vor allem Umgebungen, in denen mehrere DuckDB-Prozesse unterschiedlicher Versionen auf dieselben Dateien zugreifen.

Die Empfehlung des Teams ist entsprechend konservativ: erst auf einem Schattensystem testen, dann die Produktion umstellen. Wer eine geschäftskritische Arbeitslast betreibt, kann auf das erste Patch-Release im November warten. Auf der Werkzeugseite ändert sich der Compiler: Nach einer langen Phase auf C++11 verlangt DuckDB 2.0 einen C++17-Compiler und baut Release-Versionen standardmäßig mit Clang. Auf Linux und macOS gilt das für DuckDB und die Core-Extensions, auf Windows für die CLI, während die meisten Extensions dort noch mit MSVC gebaut werden.

DuckDB 2.0 ist keine Version, die man überstürzt einspielt. Sie erweitert den Wirkungsbereich der Datenbank: vom Bibliotheksaufruf im eigenen Prozess hin zu einem System, das als Server erreichbar ist, Daten von Objektspeichern schneller zieht, halbstrukturierte Daten ohne Umweg über Text verarbeitet und sich von Agenten steuern lässt. Wer DuckDB bisher nur für lokale Analysen genutzt hat, merkt an der Bedienung wenig Unterschied, gewinnt aber Möglichkeiten dazu. Wer es in Pipelines mit mehreren Prozessen und persistenten Dateien betreibt, sollte vor dem ersten Dateiwechsel in den Migrationsleitfaden schauen.

Quelle: duckdb.org

Deine Reaktion:
Artikel teilen:
Krötzsch-Check0 — 100
Fakten 80
Relevanz 85
Hype 30
Einschätzung 75
Redaktion 50 Stand 50 · noch keine Stimmen
Ist das Hype?
Sebastian Krötzsch
Autor

Sebastian Krötzsch

Sebastian Krötzsch schreibt auf sebask.de über Künstliche Intelligenz, Automatisierung, digitale Systeme und die Frage, was davon im Alltag wirklich nützlich ist. Ohne Buzzword-Nebel, dafür mit klarem Blick auf Praxis, Tools und echte Wirkung.