---
url: /duckdb/2.0.0.md
description: >-
  DuckDB 2.0.0 LTS（代号 Cinnamon Teal）2026 年 10 月 21 日正式发布，近 20000 次提交，Quack 协议与
  CONNECT、异步 IO、VARIANT shredding、CLI Agent Mode、PEG 解析器、触发器与 NEAREST join
  全面解析，附迁移避坑清单与真实降本案例。
---

# DuckDB 2.0.0 LTS 正式版：那只鸭子开完了服务器，转头去给 AI 打工

两个月前，2026 年 8 月 17 日，DuckDB 官方发了一篇 17 分钟长文《A Preview of DuckDB v2.0》。我当时在本站写了一篇[《那只说"不搞分布式"的鸭子，食言了》](/duckdb/v2)，结尾给的立场很明确：

> 玩，别上生产。

理由也写得很具体——那是预览版，存储格式是破坏性变更，官方自己都说"细节可能还会调整"。

然后今天，2026 年 10 月 21 日，正式版发了。

代号 **Cinnamon Teal**（肉桂水鸭，学名 *Spatula cyanoptera*，一种分布在美洲西部的红褐色鸭子——也就是此前社区口口相传的 Cyanoptera）。自 DuckDB 1.5 以来累计 **接近 20,000 次提交**，官方的原话是"这是我们迄今最大的一次特性发布"。

所以这篇文章要干两件事：把两个月前那句"别上生产"收回一半，以及把**从预览到正式之间到底变了什么**讲清楚。

## 先把版本号这件事钉死

DuckDB 现在同时存在三条版本线，选型的同学直接抄这张表：

| 版本线 | 身份 | 社区支持到 |
| --- | --- | --- |
| **2.0** | 最新 LTS（本次发布） | **至少 2027 年 10 月** |
| 1.5 | 被延长支持，事实上的 LTS | 2027 年 3 月 |
| 1.4 | 上一个 LTS | 2026 年 11 月底 |

还有两个日期值得记：**11 月 16 日会发 2.0.1 补丁版**；1.5 系列从 2.0 发布当天起就不再是"最新 stable"，补丁流向直接换向，名义 EOL 是 11 月 1 日，但那之后你等不到 1.5.7。

> 换句话说：如果你现在是 1.4 或 1.5 跑在关键链路上，真正的支持断点就是今天，不是 11 月。而 2.0 的迁移窗口，官方给了整整一年。

顺带一提，官方还单独发了一页《What's New in the Docs for 2.0》，把下面每个特性都链到了对应文档页。这个细节我很喜欢——发版不发文档等于没发。

## 从预览到正式，真正值得关心的六件事

### 1. Quack 毕业了，还顺手认了别人家的数据库

DuckDB 从 2019 年出生那天起就是 in-process 的：没有守护进程、没有端口、不用运维。1.5.3 才第一次掏出 Quack 协议，2.0 里这玩意儿从预览**打磨毕业**，性能和稳定性都上了一个台阶，并且带来一个新语句 `CONNECT`——挂载和切换远程库，一条命令搞定：

```sql
-- 服务端
CALL quack_serve(token = 'my_token');

-- 客户端
ATTACH 'quack:localhost' AS qk (TOKEN 'my_token');
CONNECT qk;
SELECT * FROM events;
```

CLI 甚至给了快捷开关，开两个终端就能玩：

```bash
duckdb -serve      # 终端 A，直接起服务
duckdb -connect    # 终端 B，直接连上
```

但真正的杀招在这里：**`CONNECT` 不只认 DuckDB**。它对 PostgreSQL、MySQL 一样有效，而且新的远程下推优化器会把 SQL 直接扔到远端服务器执行，而不是把整张表拖过网络再算。

这意味着 DuckDB 悄悄从"一个库文件"变成了"一个可以当统一 SQL 入口的客户端"。你连着 Postgres、挂着 S3 上的 Parquet、`ATTACH` 着 DuckLake，然后用同一套 SQL 方言跨着查——这个想象空间比"DuckDB 有服务器了"大得多。

安全上有个坑要提醒：`quack_serve` 默认只监听 localhost。要对外，官方明确建议**保持 localhost 并放在 TLS 终止的反向代理后面**，那个 `allow_other_hostname` 选项是为测试准备的，别在生产上开。

### 2. 异步 IO：S3 上的查询终于不憋屈了

2.0 给 Parquet 和 CSV 的读取引入了全引擎异步 IO。**I/O 层现在可以独立于查询处理层伸缩**，后台发读请求、多个请求同时在飞。

一句话总结体感：\*\*本地盘是小幅提升，对象存储上是数量级的变化。\*\*如果你的日常是 `SELECT * FROM 's3://bucket/logs/*.parquet'`，这条是你升级之后最先感觉到的。

### 3. VARIANT：从"能用"变成"一等公民"

VARIANT 在 1.5 就登场了，但 2.0 才算真正长开。官方给的定义我很喜欢——**"JSON on steroids"**，打了激素的 JSON。

和普通 JSON 一样每一行能长成不同形状，不一样的是它**不是文本**。2.0 会自动嗅出半结构化数据里藏着的公共结构，把它 **shred（切碎）**成列式表示：压缩友好、执行飞快，而且**你不用声明 schema**。整条链路端到端打通，Parquet 的 shredded VARIANT 读写也在内，配套一整个 `variant_*` 函数族。

```sql
CREATE TABLE events (payload VARIANT);
INSERT INTO events VALUES
    ('{"user": {"id": 42, "tags": ["a", "b"]}}'::JSON::VARIANT),
    ('{"event": "click", "x": 10, "y": 20}'::JSON::VARIANT);

SELECT variant_type(payload), variant_keys(payload) FROM events;
```

```
┌───────────────────────┬───────────────────────┐
│ variant_type(payload) │ variant_keys(payload) │
├───────────────────────┼───────────────────────┤
│ OBJECT                │ [user]                │
│ OBJECT                │ [event, x, y]         │
└───────────────────────┴───────────────────────┘
```

日志摄取、Agent 工具调用轨迹、请求响应 payload——这类"结构相似但天天在变"的数据，以前你要么硬套 schema 天天改表，要么塞进 TEXT 字段然后祈祷别太慢。现在不用选了。

### 4. Agent Mode：这条最有时代感

这是我在 2.0 里最喜欢的一条，也是两个月前的预览文里没有重点讲的。

现在 Claude Code、Codex、Cursor 这类编码智能体，越来越多地在替用户驱动 DuckDB CLI。于是 2.0 的 CLI 会**检测自己是不是被 Agent 跑着**，是的话自动切进 **agent mode**：

* 表格输出从带 padding 的方框改成紧凑 Markdown；
* 结果被截断时会明确说出来，而不是默默少给几行；
* 失控的查询提前掐断；
* 报错以 JSON 形式返回；
* 长查询先报预估代价，让 Agent 自己决定要不要等。

官方在 TPC-H 上测了一组：**agent mode 让模型需要读的 DuckDB 输出量减少了 59%。**

> 59% 是什么概念？按 token 计费就是接近六成的账单蒸发。一个数据库为了让自己"更适合被 AI 读"，专门改了输出格式——这件事在三年前听起来很荒诞，在 2026 年是最正常的产品决策。

想手动体验可以加 `-agent`，反过来想让 Agent 别用就 `-no-agent`。

### 5. 解析器换血，扩展可以自己开仓库了

DuckDB 从 2018 年第一个 commit 起用的都是从 PostgreSQL 继承来的 YACC/Bison 解析器（LALR(1)）。这种文法有个老毛病：语法一长大，加一条新规则就可能和老规则撞车，报 `shift/reduce` 冲突。

2.0 里官方自己写的 **PEG 解析器正式转正为默认**。PEG 按书写顺序试各条备选，加语法不再有撞车风险；扩展甚至能直接挂到文法上，注册全新的 SQL 语法。报错信息也带上了精确源码位置。Python 自己在 3.9 换 PEG 解析器，是同一个理由。

万一你真的被新解析器咬到了，临时回退：

```sql
SET enable_legacy_parser = true;
```

扩展这边，2.0 带来了大幅增强的 **C API v2**（把文件系统、表函数这些组件都暴露出去），以及一个对企业意义很大的能力——**自建扩展仓库**：

```sql
SET allow_extension_repositories = 'allowed';

CREATE EXTENSION REPOSITORY my_repo
    WITH PREFIX 'https://extensions.example.org';

INSTALL AND LOAD my_ext FROM my_repo;
```

仓库创建时 DuckDB 会拉取公钥并固定（pin）进定义里，打印 SHA-256 指纹供你带外核对。前缀可以指向本地路径、`https`、`s3`——只要 DuckDB 能读。对企业来说，扩展管理终于能纳入自己的基础设施管控范围，不用全押官方仓库。

### 6. 触发器，以及一堆"终于有了"的 SQL

**触发器**在 2.0 里补齐了：`BEFORE`/`AFTER`、`FOR EACH ROW`/`FOR EACH STATEMENT`、`REFERENCING OLD/NEW TABLE` 转换表、同事件多触发器、触发表上的 `RETURNING`、`DROP TRIGGER`。经典用法是审计表：

```sql
CREATE TRIGGER trg_audit
    AFTER UPDATE ON target
    REFERENCING OLD TABLE AS o NEW TABLE AS n
    FOR EACH STATEMENT
        INSERT INTO audit
        SELECT n.id, o.val, n.val FROM o JOIN n ON o.id = n.id;
```

但官方给的另一个例子更让我兴奋——**用触发器增量维护物化视图**。插入时按 nationality 聚合 merge 进统计表，删除时减回去并清掉归零的分组。官方原话是："触发器让我们离物化视图又近了一步"，而物化视图在他们 roadmap 的 future work 里躺了很多年。

SQL 方言这边还有一堆顺手加的：

* **`NEAREST` join**：把 top-k 相似度搜索变成一条 join 子句，向量/embedding 场景直接受益；
* **数据修改 CTE**：`INSERT`/`UPDATE`/`DELETE`/`COPY` 可以当流水线的一步写进 CTE；
* **`$x` 简写**：多数表达式位置不用再写 `getvariable('x')`；
* **嵌套 schema**：`CREATE SCHEMA finance.reports`；
* **JSON 变更函数**：`json_set`、`json_insert`、`json_replace`、`json_remove`；
* 还有标准 SQL 的 `FETCH FIRST`、`GROUP BY` 里允许 `UNNEST`，以及 `MERGE` / `UPDATE ... FROM` 在多行匹配时的语义终于有明确定义。

顺带，同日还发了 **DuckLake 1.1**（含新规范和参考实现），Iceberg 扩展补了 REST catalog 的 `ATTACH` 选项，Delta 扩展支持 `CREATE TABLE`（含分区和表属性）、时间旅行和 VARIANT。

## 谁在用，省了多少钱

**Spotify** 在 DuckCon 上分享过把 DuckDB 当用户收听历史之上的 SQL 层，官方 40k Star 博客里专门点了名。

**Arcesium**（华尔街金融科技）在 2026 年 6 月 30 日的工程博客里写了他们从 Athena 迁到 DuckDB 的 18 个月：**数千条生产 SQL、数十个金融客户、复杂的投资组合计算，整体成本砍半**。他们也没藏着掖着——Schema 推断会踩坑，S3 连接不显式指定 ENDPOINT 就报 IO Error，有些参数文档里不好找得读源码。作者的结论很实在：这条路不容易，但对金融科技这种查询多变、并发高、不依赖 PB 级扫描的场景，值得这笔迁移成本。

**Definite**（分析平台创业公司）把整个栈建在 DuckDB + DuckLake 上，账单是这么个画风：

| 组件 | Snowflake + Looker | Definite (DuckDB/DuckLake) |
| --- | --- | --- |
| 计算 | $2,000–5,000/月 | 包含 |
| 存储 | $40–80/月 | $20–40/月 |
| BI 工具 | $1,000–3,000/月 | 包含 |
| 连接器 (Fivetran) | $500–2,000/月 | 包含 |
| **总计** | **$3,500–10,000/月** | **$250–500/月** |

这不是省 20%，这是差一个数量级。他们的仪表盘典型查询在 **200–400ms**，而 Snowflake X-Small 需要 2–5 秒。

**MotherDuck**（DuckDB 的商业云服务）2026 年 Q1 付费团队数突破了 10,000。

> 项目管理上也有个背景值得知道：DuckDB 背后的公司 DuckLabs 明确拒绝过风险投资，理由是不想让项目方向被推向变现；IP 由独立非营利组织 DuckDB Foundation 持有，章程保证 MIT 协议永久开源。2026 年 8 月底 DuckLabs 宣布加入 AWS，团队仍留在阿姆斯特丹，官方同期更新的支持政策里承诺加大文档、教育和社区投入，并在今年秋天增设 Technical Advisory Board。

## 初体验：五分钟跑起来

CLI 和 Python 客户端今天已经放出来了（Go、R、Java 和部分扩展会晚几天）。

```bash
pip install -U duckdb
python -c "import duckdb; print(duckdb.__version__)"
```

CLI 用户去 [GitHub Releases](https://github.com/duckdb/duckdb/releases/tag/v2.0.0) 抓对应平台构建，解压即用。

**玩一下服务器模式**，开两个终端：

```bash
duckdb -serve      # 终端 A
duckdb -connect    # 终端 B
```

**玩一下 VARIANT：**

```sql
CREATE TABLE logs (payload VARIANT);
INSERT INTO logs VALUES
    ('{"level":"ERROR","msg":"disk full","host":"a-01"}'::JSON::VARIANT),
    ('{"level":"INFO","msg":"ok","host":"a-02"}'::JSON::VARIANT);

SELECT variant_extract(payload, '$.level') AS lvl, count(*)
FROM logs GROUP BY lvl;
```

**玩一下触发器**（审计表最小闭环）：

```sql
CREATE TABLE t (id INTEGER, val VARCHAR);
CREATE TABLE audit (id INTEGER, old_val VARCHAR, new_val VARCHAR);

CREATE TRIGGER trg_audit AFTER UPDATE ON t
REFERENCING OLD TABLE AS o NEW TABLE AS n
FOR EACH STATEMENT
    INSERT INTO audit
    SELECT n.id, o.val, n.val FROM o JOIN n ON o.id = n.id;
```

## 上生产之前，先把这四条读完

两个月前我说"别上生产"，现在我把话改成——**可以开始迁，但按这四条来**。

1. **存储格式是破坏性变更**。2.0 之前的 DuckDB **读不了** 2.0 创建的库文件；反过来 2.0 能读写你的老库文件，且写出来的老文件仍能被老版本读。所以升级前先想清楚共享文件的版本锁定策略。
2. **lambda 语法默认换了**。旧的单箭头 `x -> x + 1` 已默认禁用，改成 Python 风格：

   ```sql
   SELECT list_transform([1, 2, 3], lambda x: x + 1);
   ```

   临时回退用 `SET lambda_syntax = 'enable_single_arrow';`，但**这个开关和旧语法会在 v2.1 彻底移除**，别把它当长期方案。
3. **ICU 依赖被移除了**。时区、日历、排序规则由 `icu` 扩展自己实现，时区数据直接由 IANA 库压到约 45 kB——行为不变，而且更快（2500 万行时区转换 0.24s → 0.11s）。
4. **平台与构建**：编译器要求升到 C++17，发布构建默认换 Clang；amalgamation 构建已弃用；**macOS x86\_64 进入淘汰流程，2.1 起停止支持**，社区扩展已经不再为该平台构建。

最后一条来自官方自己的建议，我原样转述：**先在影子系统上测 2.0.0，再切生产；如果是关键业务负载，可以等 11 月的第一个补丁版。**

> 一只 2019 年靠"我就是不开服务器"出圈的鸭子，2026 年有了自己的网络协议、学会了跨库下推、把输出格式改成 AI 更爱读的样子，还给自己挂了个 LTS 标签。它不是背叛了初衷——它只是从"你不需要集群"走到了"你依然不需要集群，但你想连的时候能连"。单二进制的简洁性它还没丢，这已经相当克制了。

## 进阶

想系统学 DuckDB，可以先看[认识DuckDB](/duckdb/introduction)和[玩转DuckDB](/duckdb/play-duckdb)。想看它在超大规模 CSV 上的表现，[玩转超亿级CSV](/duckdb/csv)和[百亿级数据性能测试](/duckdb/csv-big)里有完整的实测数据。两个月前那篇[2.0 预览版解析](/duckdb/v2)可以作为对照阅读。

官方那份 2.0 发布长文、异步 IO 与 PEG 解析器的专题博客，以及《What's New in the Docs for 2.0》导航页，都值得通读一遍。

更多开源技术干货和学习资料，关注公众号「遇码」，领取专属福利。
