DuckDB 2.0 的 Quack 服务:认证一步连撞 3 个坑
DuckDB 2.0 的旗舰特性里,Quack 排第一位——DuckDB 第一次有了官方 client/server 协议:一个实例当服务器,其他实例通过网络连进来查询。发布当天我就想试:本机双进程跑通「服务器建表、客户端远程读写」的全链路。结果在认证这一步连撞三个坑,每个坑的报错信息都指错方向。这篇是一手实测记录,环境:WSL2,duckdb==2.0.0(Python 包),同机双连接模拟双进程。
先说结论:全链路最终跑通——远程读、远程写、count/max 聚合、服务端视角数据一致。但官方博客那句三行示例,照抄跑不通。
● ● ●
坑 1:quack_serve 没有 host/port 参数
起服务的第一直觉写法:
CALL quack_serve(host='127.0.0.1', port=9494, token='my_token');报错:Invalid named parameter "host"。查函数签名,真实参数是这些:listen_uri、disable_ssl、ssl_cert_file、ssl_key_file、allow_other_hostname、token、secret、create_secret_if_not_exists——地址和端口合并在 listen_uri 一个 URI 参数里:
CALL quack_serve(listen_uri='quack://127.0.0.1:9494', token='my_token');返回三元组:quack URI、实际 HTTP 监听地址、token——服务即起。另外无参调用 CALL quack_serve() 也能起,默认听 localhost:9494,返回值里还自动生成一个随机 token。
● ● ●
坑 2:token 不走 ATTACH 选项
客户端连入,我又按直觉写:
ATTACH 'quack://127.0.0.1:9494' AS remote (TOKEN 'my_token');报错:Unrecognized option for attach "token"。查官方文档,token 的正确去处是 quack 类型的 secret:
CREATE SECRET (TYPE quack, TOKEN 'my_token');
ATTACH 'quack://127.0.0.1:9494' AS remote;
secret 机制比 ATTACH 选项合理——token 不落 SQL 文本、可按作用域管理。但报错信息只说「选项不认识」,不说该往哪走,这一步卡了我最久。
● ● ●
坑 3:URI 的斜杠数量反直觉
secret 建好,ATTACH 还是失败:Cannot open file "quack://127.0.0.1:9494/"——双斜杠形态被当成本地文件路径了。正确写法是单斜杠都不带的 host:port 形态:
ATTACH 'quack:127.0.0.1:9494' AS remote;服务端 listen_uri 用 quack:// 双斜杠,客户端 ATTACH 用 quack: 冒号直连——两端形态不一致,没有文档明说,纯实测撞出来的。
● ● ●
跑通后的全链路
三坑绕过,剩下全是坦途:
-- 服务端
CREATE TABLE t AS SELECT 42 AS answer;
CALL quack_serve(listen_uri='quack://127.0.0.1:9494', token='my_token');
-- 客户端
CREATE SECRET (TYPE quack, TOKEN 'my_token');
ATTACH 'quack:127.0.0.1:9494' AS remote;
SELECT * FROM remote.t; -- (42,)
INSERT INTO remote.t VALUES (43), (44);
SELECT count(*), max(answer) FROM remote.t; -- (3, 44)
服务端自己查 t 表,看到的正是 42/43/44——写入真实落在了服务器上。查询语义就是普通 SQL:远程表和本地表可以 JOIN,聚合下推由引擎处理。
一个运维细节:quack_serve 起的是常驻服务线程——脚本里调用它之后,进程不会随查询结束退出。交互式用没问题,写自动化脚本记得管理进程生命周期(我的验证脚本每次都要 timeout 杀进程)。
● ● ●
三点判断
一、Quack 的设计本身是好的:secret 认证、默认只听 localhost、官方推荐「localhost + TLS 反向代理」而非裸开端口——安全默认值都在。扣分项是报错质量:三个坑的报错(参数不存在/选项不认识/文件打不开)没有一个指向正确答案。
二、适用边界想清楚再上:Quack 解决的是「多个客户端共享一个 DuckDB」的场景——小团队共享分析库、应用读分析数据。它不改变单写者的并发模型:写入路径仍要收敛到单进程串行事务的舒适区。
三、这六个坑(本篇三个 + 上一篇文章的触发器、湖仓、VARIANT 坑)全部进了我的书稿修订。《DuckDB 实战》第 5 章的 Quack 三部曲,现在是双进程实测过的版本。配套代码在文末开源仓,一条命令复现本文全流程。
● ● ●
参考来源
https://duckdb.org/2026/10/21/announcing-duckdb-200-lts-cinnamon-teal.html
https://duckdb.org/2026/05/12/quack-remote-protocol.html
https://duckdb.org/docs/current/quack/overview.html
https://github.com/duckdb/duckdb-quack
https://github.com/alitrack/duckdb-book-code