启动 Quack 协议:从单进程库到数据库服务器
图:DuckDB v2.0 桂红鸭主题插画。来源:duckdb.org
「我们本以为只是扩展 DuckDB 让人能和其他 DuckDB 对话,社区却说不,并自己构建了独立客户端。」官方团队在 2026 年 8 月 17 日发布的 DuckDB v2.0 预览版(代号 Cyanoptera,桂红鸭)中这样记录 Quack 协议的演进背景。自 2026 年 3 月发布 v1.5 以来,开发团队已合并超过 10,000 个提交(commits),迎来了嵌入式分析数据库历史上规模最大的一次架构升级。官方明确宣告:「如果说去年是数据湖仓(Lakehouse)之年,那么本版本开启了 DuckDB 作为数据库服务器的新纪元。」
这一转变的核心在于 Quack 扩展协议的引入。在过去,DuckDB 始终以进程内嵌入式 C++ 库的形式运行,应用程序通过 API 共享内存直接调用查询引擎。而在 v2.0 中,开发者只需执行 CALL quack_serve() 即可将任意 DuckDB 实例暴露为可被远程连接的数据库服务,客户端通过 ATTACH 'quack:server.example.com' 就能跨越网络边界进行数据交互。DuckDB 正在打破嵌入式分析引擎与客户端/服务器(Client/Server)数据库之间的天然屏障,以主动姿态进入 PostgreSQL 和 MySQL 主导的服务型数据库市场。
远程 pushdown 与触发器:补齐长程服务的最后拼图
在 Quack 协议落地之前,跨库查询依赖把远程表全部拉取到本地进程内存,极易引发网络 IO 瘫痪与内存溢出。v2.0 引入的 CONNECT 语句彻底改写了这一模式,支持直接将 SQL 转化为远程数据库的原生查询。通过编号 #22914 的远程下推(Pushdown)优化器,DuckDB 能将过滤谓词与聚合算子直接下推至 PostgreSQL 和 MySQL 远端引擎执行,仅返回计算好的结果集。在跨源联表场景下,下推机制使网络数据传输量显著降低,避免了无意义的巨量原始数据加载。
除了网络连接层面的破局,v2.0 在数据库基础能力上也做出了突破性的补充,首次完整支持了触发器(Triggers)系统。引擎现在提供了 BEFORE 和 AFTER 事件触发、FOR EACH ROW 与 FOR EACH STATEMENT 粒度控制、过渡表(Transition Tables,即 REFERENCING OLD/NEW TABLE)以及 RETURNING 子句。官方团队透露,后续许多内部核心功能都将基于这套触发器机制构建。这说明 DuckDB 的事务与并发机制(MVCC,多版本并发控制)不再局限于短期单用户会话,而是全面转向支持长程运行、多租户接入的服务端架构。
异步 I/O 与 VARIANT 类型:突破单机计算的吞吐上限
图:DuckDB v2.0 异步 I/O 架构设计。来源:duckdb.org
单机解耦服务化后,数据读写效率成为决定服务端响应速度的关键指标。DuckDB v2.0 实现了 I/O 层与查询处理层的独立扩展,彻底重构了底层数据流架构。在编号 #23662 的更新中,Parquet 格式率先获得了异步 I/O 和异步写入支持,CSV(#23961)与 DuckDB 自有存储格式(#24654)也已跟进,同时提供了内存映射(MMAP)与直接 I/O(DIRECT_IO)模式。I/O 读写与 CPU 计算算子的并行化,消除了大型 Parquet 文件加载时的线程阻塞,使分析吞吐不再受限于同步文件读取延迟。
半结构化数据处理方面,v2.0 正式将 VARIANT 提升为一等公民类型。通过自动结构提取(Shredding)技术,引擎能在读取时自动识别 JSON 等复杂数据中的公共结构,并转换为高压缩率列式存储。结合编号 #20912 的直接解析执行与编号 #22478 的抽取下推,复杂 JSON 日志的查询时延大幅缩短。在半结构化分析场景中,开发者无需提前定义繁重的数据 Schema,即可获得接近原生数值列的向量化查询性能。
为支撑存储层的高效演进,DuckDB 升级了存储格式至 v2.0.0(#22875),默认开启 DICT_FSST 字符串压缩算法(#23733),并实现了列元数据的延迟加载与紧凑删除存储(#24336)。在算法层面,优化器支持将局部聚合下推至连接算子之下(#22572),并在内存不足时自动将聚合状态下刷至磁盘(Spill to Disk,#24499)。在百万条边的单源图可达性基准测试中,重写后的递归通用表表达式(Recursive CTE)引擎将查询耗时从 v1.5.4 的 4.90 秒降低至 0.12 秒,实现了近 40 倍的性能提升。这证明了向量化引擎在图计算等复杂迭代任务上的工程潜力。
自研 PEG 解析器与 C API 稳定:解绑历史包袱的架构独立
DuckDB v2.0 移除了长期使用的 PostgreSQL 衍生 SQL 解析器,换上了全新的基于 PEG(Parsing Expression Grammar,语法图解析)的解析引擎(#22194)。新解析器支持挂钩自定义语法扩展,并能给出精确的错误定位上下文,同时原生提供 Spark 语法兼容模式(dialect_compatibility_mode = 'spark')。摆脱历史 C 代码解析器的约束后,DuckDB 在语法扩充与方言兼容上的迭代周期将缩短,能够更快响应混合负载的 SQL 需求。
在基础依赖管理上,v2.0 移除了对外部 ICU(International Components for Unicode)库的硬连接,改由内置的轻量化扩展接管时区与排序(Collation)逻辑。替换后,IANA 时区数据被高度压缩至约 45kB。在 2500 万行数据的时区转换测试中,查询耗时从 0.24 秒缩短至 0.11 秒(提升 2.2 倍);在 500 万行德文 Collation 过滤测试中,耗时从 0.15 秒降低至 0.06 秒(提升 2.6 倍)。极小化的二进制体积配合翻倍的基准性能,为高密度容器部署和边缘节点运行铺平了道路。
对第三方扩展开发者而言,v2.0 推出的声明式 C API 规范(api_spec/)代表了生态成熟度的里程碑。扩展只需基于规范编译一次,即可在后续 DuckDB 主版本更新中保持永久兼容。构建流程通过持续集成(CI)工具自动校验规范与头文件的一致性,防止符号漂移。统一的符号版本、自定义内存分配器与静态链接支持,使得围绕 DuckDB 研发商业闭源插件或特定领域算子的基础设施生态具备了坚实基础。
嵌入式基因与多租户并发:底层架构的正面交锋
虽然 DuckDB 诞生之初就具备事务隔离与 MVCC 设计,但在单用户嵌入式场景下,多连接并发与资源抢占问题并未得到充分的压力检验。随着 Quack 协议将其推向长期运行的数据库服务器形态,DuckDB 必须在真正的多租户并发与复杂内存管控上直面 PostgreSQL 和 ClickHouse 等成熟系统。在 Hacker News 社区热帖(49330781,获得 644 点赞与 116 条讨论)中,众多开发者针对数据管线拆分与服务化部署展开了热烈讨论。
社区关注的焦点集中在资源隔离与查询调度上。分析型数据库在应对大并发小查询与超大分析查询混合涌入时,很容易面临内存爆池或线程饥饿。与传统针对服务端设计的数据库相比,DuckDB 长期针对单进程优化的执行器需要进一步验证其在高并发长程运行下的稳定性。
与此同时,Quack 协议也改变了数据管线的拓扑结构。过去的典型架构往往依赖 ETL 工具将数据抽取至集中式分析仓库,而 DuckDB v2.0 的分布式 pushdown 能力允许多个 DuckDB 节点协同计算,甚至把 SQL 下推回上游事务库。这种轻量级计算网络的兴起,将对重型数仓的统治地位形成有力补充与局部替代。
嵌入式引擎的边界突破
DuckDB v2.0 预览版的发布标志着数据库领域的一次范式重构。Quack 协议、触发器系统、异步 I/O 与稳定 C API 的组合,推动着这个曾经的「Python 进程内分析加速器」迈向独立运作的数据库服务器。
对于数据工程界而言,v2.0 的意义在于重新定义了轻量级数据库的能力上限。当一个单文件部署、启动毫秒级的分析引擎能够对外提供标准查询服务并下推计算负载时,传统客户端与服务端的二元划分已经开始瓦解。现在真正的考验在于,当它正式进入 PostgreSQL 和 ClickHouse 的腹地时,能否在长期高并发的战场上延续其在单机分析领域的传奇。
参考链接:
- DuckDB v2.0 Preview 官方发布公告
- Hacker News 社区讨论帖