发布 pg_ducklake v1.0

@qsliu2017
2026年6月17日

我们于一月份启动了 pg_ducklake 项目,今天正式发布 v1.0 —— 首个生产就绪版本。此版本由三大特点定义:

  1. 完整的 DuckLake 工作流。v1.0 将 DuckLake 的大部分功能集带到了 PostgreSQL SQL 中:DML、模式演化、时间旅行、分区、排序表、variant 类型、ACID 事务以及自动维护。每个表对任何 DuckDB 客户端保持开放可读。

  2. 生产级品质。pg_ducklake 专为在 OLTP 数据库内部运行而调优:在持续负载下保持稳定,内存使用节制有度,并为 DuckLake 提供最快的摄取路径。

  3. 独立且兼容。pg_ducklake 最初是作为 pg_duckdb 的一个分支开始的。v1.0 不再派生或依赖它。它是一个自包含的扩展,构建在我们提取的可复用内核 libpgduckdb 之上,并且保持与 pg_duckdb 的兼容性。

完整的 DuckLake 工作流

v1.0 将完整的 DuckLake 工作流带到了 PostgreSQL SQL 中:

  • 核心 DML:INSERT(包括 CTAS 和 INSERT … SELECT)、SELECT、UPDATE、DELETE 和 MERGE。
  • 模式演化
  • 时间旅行和快照
  • 数据变更馈送:查询快照之间插入、删除和变更的行。
  • 分区和排序表:按列或转换对文件进行分区,并在文件内保持行有序,以实现更快的剪枝和更好的压缩。
  • ACID 事务:通过 PostgreSQL 事务模型实现,并支持冻结/导出为 .ducklake 快照。
  • 自动维护:后台工作进程负责刷新、压缩、重写、过期和清理,每个操作也支持按需执行。
  • Variant 类型

由于 pg_ducklake 遵循 DuckLake 标准,其表可以直接从任何 DuckDB 客户端读取。pg_ducklake 负责在 OLTP 友好的写入路径上进行数据摄取,而您可以将繁重、长时间运行的分析工作负载卸载到独立的 DuckDB 引擎上,无需复制数据,也无需迁移。

在 DuckLake 之上,pg_ducklake 还增加了基于角色的访问控制、用于远程和冻结目录的外部数据包装器(ducklake_fdw)以及 IMPORT FOREIGN SCHEMA。

部分 DuckLake 功能尚未开放:

  • DuckLake 视图和宏。
  • Parquet 级加密。
  • 注册外部 Parquet 文件(add_data_files)。

完整的最新功能矩阵请参见功能覆盖文档。

专为快速摄取而设计

DuckLake 将其元数据存储在 SQL 数据库中,而 pg_ducklake 运行在该数据库内部,因此它可以走最短的写入路径。

  • 数据内联。小写入被缓冲在 PostgreSQL 目录中,对所有读取者立即可见,并批量刷新到 Parquet。这避免了基于文件的湖仓系统常见的小文件问题。该功能默认开启。
  • 直接插入。对于常见的批量加载场景,规划器钩子将行直接写入堆页面,跳过了经由目录的 DuckDB 反解析和序列化往返过程。

在我们的流式基准测试中,这使得小批量插入比 DuckDB+DuckLake 快 5.8 倍,达到原始 PostgreSQL 堆插入性能的 2.6 倍以内。

对于持续复制,可将 pg_ducklake 与 pg_duckpipe 配合使用,后者通过 PostgreSQL 的 WAL 将变更从堆表流式传输到 DuckLake 表中,无需 Kafka 和 Debezium。两者结合使 pg_ducklake 天然适合 CDC、事件流和 ETL 管道。

独立且兼容

pg_ducklake 经历了三个阶段。它最初是作为 pg_duckdb 的一个分支开始的。三月份,我们将其转变为仍然依赖 pg_duckdb 的独立扩展。v1.0 迈出了最后一步:pg_ducklake 现在是一个完全独立的扩展,不再依赖 pg_duckdb,同时保持与之兼容。(这两个早期阶段作为 legacy-0 和 legacy-1 分支保留在我们的仓库中。)

我们通过将 pg_duckdb 中可复用的“PostgreSQL 扩展中的 DuckDB”机制提取到一个内核库 libpgduckdb 中实现了这一目标:DuckDB 实例生命周期、规划器卸载原语、用于 DuckDB 的 PostgreSQL 堆扫描、自定义扫描执行以及 PG 端包装器。pg_ducklake 不再依赖 pg_duckdb,而是构建在此内核之上,其他扩展也可以如此。该仓库是一个单体仓库:

  • libpgduckdb/:内核。
  • pg_ducklake/:主要扩展,PostgreSQL 中的 DuckLake 表。
  • pg_duckdb/examples/pg_vortex/:保留在树中,以确保内核保持可复用,并且绝不会破坏 pg_duckdb 的行为。

一个精小、聚焦的内核是我们能够加固的。DuckDB(以及与之相伴的 pg_duckdb)是为短期分析会话而构建的,而 pg_ducklake 则在长期运行的 PostgreSQL 后端中运行,进行持续摄取。我们的目标是将 libpgduckdb 优化为具备崩溃恢复能力、内存可控且生命周期可预测,使其能够在长期运行的数据库中蓬勃发展。

由于 pg_ducklake 不再修改或依赖 pg_duckdb,两者可以并列运行。现有的 pg_duckdb 用户添加 pg_ducklake 无需更改其现有设置。

快速开始

运行预装了 pg_ducklake 的 PostgreSQL:

docker run -d \
 --name pgducklake \
 -e POSTGRES_PASSWORD=duckdb \
 pgducklake/pgducklake:18-main
docker exec -it pgducklake psql

然后创建您的第一个湖仓表:

CREATE TABLE my_table (id INT, name TEXT, age INT) USING ducklake;
INSERT INTO my_table VALUES (1, 'Alice', 25), (2, 'Bob', 30);
SELECT * FROM my_table;

pg_ducklake 支持 PostgreSQL 14 至 18,可通过 make install 从源码构建,并采用 MIT 许可证。

下一步计划

我们将继续加固 pg_ducklake 以支持长期运行的摄取,补齐剩余的 DuckLake 功能缺口,并将直接插入快速路径扩展到更多写入模式。

我们现在可以快速交付功能,因此瓶颈在于了解应该构建什么。告诉我们您的需求!功能请求和错误报告是您能提供的最有价值的贡献。尝试 pg_ducklake,并告诉我们它如何适应您的工作流程。

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐