PostgreSQL码农集散地

DuckLake 更新, 支持Iceberg互换数据及Geometry类型等

本期播客

DuckLake 更新, 支持Iceberg互换数据及Geometry类型等

DuckLake是DuckDB的一款扩展插件, 之前有过详细的架构介绍, 简单来说就是 duckdb计算引擎 + 元数据管理 + 湖 + 表格存储格式 的集合.

DuckLake 发布0.3, 带来诸多特性, 包括对DuckDB 1.4的特性引入、支持读写iceberg、支持geometry类型等.

下面来看官方报道, 以下内容翻译自: https://duckdb.org/2025/09/17/ducklake-03.html

DuckLake 更新, 支持Iceberg互换数据及Geometry类型等

TL;DR:我们正在发布 DuckLake 规范和DuckDB ducklake扩展的 0.3 版本。

过去两个月,团队的重点是让 DuckLake 尽可能地强大。除此之外,我们还实现了一系列功能,让 DuckLake 的运行体验更加流畅。在本文中,我们将讨论 DuckDB ducklake扩展和 DuckLake v0.3 规范中的更新。

ducklake扩展中的新功能

DuckDB v1.4.0 中的扩展ducklake包含多项新功能。要试用本文中描述的功能,请确保您已安装 DuckDB v1.4.0 并且所有扩展均已更新。您可以通过运行以下命令来实现:

UPDATE EXTENSIONS;  

与 Iceberg 的互操作性

在 DuckDB iceberg扩展的支持下,可以在 DuckLake 和 Iceberg 之间复制数据。

Iceberg 和 DuckLake 的设置

INSTALL iceberg;  
LOAD iceberg;  
INSTALL httpfs;  
LOAD httpfs;  
-- Basic Iceberg setup from https://github.com/duckdb/duckdb-iceberg/blob/main/scripts/start-rest-catalog.sh  
CREATE SECRET (  
    TYPE S3,  
    KEY_ID 'admin',  
    SECRET 'password',  
    ENDPOINT '127.0.0.1:9000',  
    URL_STYLE 'path',  
    USE_SSL false
);  
ATTACH '' AS iceberg_datalake (  
    TYPE iceberg,  
    CLIENT_ID 'admin',  
    CLIENT_SECRET 'password',  
    ENDPOINT 'http://127.0.0.1:8181'
);  
ATTACH 'ducklake:my_ducklake.ducklake' AS ducklake (DATA_PATH 'data/');  

现在您可以从 Iceberg 复制到 DuckLake。

CREATE SCHEMA iceberg_datalake.default;  
CREATE TABLE iceberg_datalake.default.iceberg_table AS  
    SELECT a FROM range(4) t(a);  
COPY FROM DATABASE iceberg_datalake TO ducklake;  

假设schema已经在 Iceberg 中创建,那么从 DuckLake 复制到 Iceberg也是可行的。

-- Assuming Iceberg catalog is empty since the COPY command does  
-- not replace tables  
CREATE SCHEMA iceberg_datalake.main;  
CREATE TABLE ducklake.default.ducklake_table AS  
    SELECT a FROM range(4) t(a);  
COPY FROM DATABASE ducklake TO iceberg_datalake;  

这些示例是最新快照的数据副本(即深度复制),这意味着只有数据从 Iceberg 迁移到 DuckLake,反之亦然。Iceberg 和 DuckLake 之间也支持纯元数据复制。主要区别在于纯元数据复制不会复制底层数据,而只会复制元数据,包括所有快照历史记录。这意味着您可以像查询 DuckLake 表一样查询 Iceberg 表的先前快照。

CREATE SCHEMA iceberg_datalake.default;  
CREATE TABLE iceberg_datalake.default.iceberg_table AS  
    SELECT a FROM range(4) t(a); -- version 0  
INSERT INTO iceberg_datalake.default.iceberg_table  
    SELECT a FROM range(4, 10) t(a); -- version 1  
CALL iceberg_to_ducklake('iceberg_datalake', 'ducklake');  

现在您可以查询任何版本的iceberg表,就像它是 DuckLake 表一样。

FROM ducklake.default.iceberg_table AT (VERSION => 0);  

┌───────┐  
│   a   │  
│ int64 │  
├───────┤  
│     0 │  
│     1 │  
│     2 │  
│     3 │  
└───────┘  

MERGE INTO 语句

由于 DuckDB 1.4 已支持MERGE INTO功能,因此自此版本起,也可以在ducklake扩展中使用此功能。这在不支持主键但仍希望支持更新插入(即plus UPDATE/INSERT)功能的 OLAP 系统中非常常见。

CREATE TABLE Stock(item_id INTEGER, balance INTEGER);  
INSERT INTO Stock VALUES (10, 2200), (20, 1900);  

WITH new_stocks(item_id, volume) AS (VALUES (20, 2200), (30, 1900))  
    MERGE INTO Stock USING new_stocks USING (item_id)  
    WHEN MATCHED THEN UPDATE SET balance = balance + volume  
    WHEN NOT MATCHED THEN INSERT VALUES (new_stocks.item_id, new_stocks.volume);  
FROM Stock;  

┌─────────┬─────────┐  
│ item_id │ balance │  
│  int32  │  int32  │  
├─────────┼─────────┤  
│      10 │    2200 │  
│      20 │    4100 │  
│      30 │    1900 │  
└─────────┴─────────┘  

MERGE INTO还支持更复杂的条件和DELETE语句。

WITH deletes(item_id, delete_threshold) AS (VALUES (10, 3000))  
    MERGE INTO Stock USING deletes USING (item_id)  
    WHEN MATCHED AND balance < delete_threshold THEN DELETE;  
FROM Stock;  

┌─────────┬─────────┐  
│ item_id │ balance │  
│  int32  │  int32  │  
├─────────┼─────────┤  
│      20 │    4100 │  
│      30 │    1900 │  
└─────────┴─────────┘  

CHECKPOINT 语句

DuckLake 现在还支持CHECKPOINT语句。在 DuckLake 中,该语句按顺序运行一系列维护函数。这包括刷新inlining数据、使快照过期、压缩文件、重写被大量删除的文件以及清理旧文件或孤立文件。CHECKPOINT语句可以通过一些全局选项进行配置,这些选项可以通过ducklake.set_option函数设置。

ATTACH 'ducklake:my_ducklake.ducklake' AS my_ducklake;  
USE my_ducklake;  
CHECKPOINT;  

更快的插入

如果某个查询中每个线程的输出都达到所需的大小(即不太小),则设置per_thread_output选项很可能会加快 DuckLake 中的插入过程。如果您拥有大量线程,并且每个线程的输出不是很重要,则使用per_thread_output选项可能不会带来太多性能提升,反而会生成大量小文件,从而影响读取性能。如果您运行的设置是 DuckDB 位于 EC2 实例中,并且具有非常高的网络带宽(高达 100 Gbps)来写入 S3,那么此选项将为您带来很大的好处。

在以下基准测试中,我们确实发现启用per_thread_output后性能提高了约 25% :

.timer on  
ATTACH 'ducklake:my_ducklake.ducklake' AS ducklake;  
CREATE TABLE sample_table AS SELECT * FROM range(1_000_000_000);  
-- 4.5 seconds  
CREATE TABLE slow_copy AS SELECT * FROM sample_table;  

-- enable the option  
CALL ducklake.set_option('per_thread_output', true);  

-- 3.4 seconds  
CREATE TABLE fast_copy AS SELECT * FROM sample_table;  

此功能由社区成员Julian Meyers贡献。

DuckLake 规范的更新

支持几何类型

DuckLake 现已支持几何类型。这意味着您现在可以将 DuckLake 作为后端,使用 DuckDB spatial 扩展的大部分功能。请参阅支持的几何图元文档。

INSTALL spatial;  
LOAD spatial;  

ATTACH 'ducklake:my_ducklake.ducklake' AS ducklake;  
CREATE TABLE geometry_table (polygons GEOMETRY);  
INSERT INTO geometry_table VALUES ('POLYGON((0 0, 0 1, 1 1, 1 0, 0 0))');  
SELECT  
    polygons,  
    ST_Area(polygons) AS area  
FROM geometry_table;  

┌─────────────────────────────────────┬────────┐  
│              polygons               │  area  │  
│              geometry               │ double │  
├─────────────────────────────────────┼────────┤  
│ POLYGON ((0 0, 0 1, 1 1, 1 0, 0 0)) │  1.0   │  
└─────────────────────────────────────┴────────┘  

请注意,几何支持目前处于实验阶段,并且缺少过滤器下推、数据inlining和坐标系跟踪等功能。

快照支持auth commit信息

我们还启用了一些功能,让您在 DuckLake 中执行新事务时能够创建提交。此功能极大地满足了审计需求。例如在时间旅行表中的应用, 标记版本是被谁修改的.

参考: https://ducklake.select/docs/stable/duckdb/usage/snapshots#adding-a-commit-message-to-a-snapshot

从 v0.2 迁移到 v0.3

您无需担心在不同版本的 DuckLake 规范之间手动迁移。当您将新ducklake扩展程序连接到现有的 DuckLake 时,该扩展程序将使用以下 SQL 脚本将元数据目录更新到 0.3 版本。

ducklake扩展用于从 DuckLake v0.2 迁移到 v0.3 的 SQL 脚本。

ALTER TABLE ducklake_name_mapping ADD COLUMN IF NOT EXISTS is_partition BOOLEAN DEFAULT false;  
ALTER TABLE ducklake_snapshot_changes ADD COLUMN IF NOT EXISTS author VARCHAR DEFAULT NULL;  
ALTER TABLE ducklake_snapshot_changes ADD COLUMN IF NOT EXISTS commit_message VARCHAR DEFAULT NULL;  
ALTER TABLE ducklake_snapshot_changes ADD COLUMN IF NOT EXISTS commit_extra_info VARCHAR DEFAULT NULL;  
UPDATE ducklake_metadata SET value = '0.3' WHERE key = 'version';  
CREATE TABLE IF NOT EXISTS ducklake_schema_versions(begin_snapshot BIGINT, schema_version BIGINT);  
INSERT INTO ducklake_schema_versions SELECT * FROM (SELECT MIN(snapshot_id), schema_version FROM ducklake_snapshot GROUP BY schema_version ORDER BY schema_version) t WHERE NOT EXISTS (SELECT 1 FROM ducklake_schema_versions);  
ALTER TABLE IF EXISTS ducklake_file_column_statistics RENAME TO ducklake_file_column_stats;  
ALTER TABLE ducklake_file_column_stats ADD COLUMN IF NOT EXISTS extra_stats VARCHAR DEFAULT NULL;  
ALTER TABLE ducklake_table_column_stats ADD COLUMN IF NOT EXISTS extra_stats VARCHAR DEFAULT NULL;  

指南和路线图

上个月,我们还准备了一些指南来帮助您采用 DuckLake,并涵盖一些不属于 DuckLake 功能但可以帮助您顺利运行 DuckLake 的主题。

  • 不同格式之间的迁移: https://ducklake.select/docs/stable/duckdb/migrations/duckdb_to_ducklake
  • 备份和恢复: https://ducklake.select/docs/stable/duckdb/guides/backups_and_recovery
  • 访问控制: https://ducklake.select/docs/stable/duckdb/guides/access_control

最后,我们还发布了一份路线图,展示了即将推出的 DuckLake 版本中计划推出的功能。

  • https://ducklake.select/roadmap

参考

《用 “DuckDB/DuckLake + ECharts + LLM” 实现一个BI智能数据可视化产品?》

《再见分布式湖仓一体, 你好DuckLake》

https://duckdb.org/2025/09/17/ducklake-03.html