摘要: DuckDB 在 8 月 17 日公開 v2.0 預覽版 Cyanoptera,正式版排在秋季;自 v1.5 以來累積超過一萬次 commit。新版更換 SQL 解析器、升級預設儲存格式、重寫 C API,並讓 Quack 伺服器擴充套件轉正式;文中提醒升級前應先測試。
DuckDB 於 8 月 17 日公開 v2.0 預覽版,代號「Cyanoptera」,名字來自栗胸鴨,這種鴨分布在美洲、羽色偏紅棕。正式版本排在今秋推出。從三月的 v1.5 算起,這段時間累積的 commit 已超過一萬次。這回不只是往功能清單上多添幾筆:換上全新的 SQL 解析器、把預設儲存格式改版、重寫 C API,另外還夾帶少數經過仔細斟酌的破壞性變更。向來只做單機內嵌的 DuckDB,這回把伺服器模式推上了主舞台。
為什麼是大改版
團隊說得毫不含糊:版號往上跳不是為了儀式。v2.0 移除 PostgreSQL 衍生的解析器,預設儲存格式升到 2.0,C API 也重做一遍。這三項都牽動檔案格式與二進位介面的根基,與其讓舊包袱拖著、在上頭繼續疊功能,不如一次把話講明白。相關內容大半早已在 DuckCon #7 的「State of the Duck」演講中預告,這篇預覽文則把要點濃縮成十項。
DuckDB 當伺服器
使用者感受最強的一項,是 quack 擴充套件從實驗走向正式:現在任何 DuckDB 行程都能把資料庫服務到網路上,另一端以原生協定(加上 CONNECT 語法)連線進來。DuckDB 打從第一天就是 in-process 資料庫,client/server 模式被使用者敲碗許多年,這次總算成真。長時間運行的服務、多人共同取用、連線集中管理——以往得在外頭另外包一層才能做的事,如今有了原生解法。觸發器同樣著眼於長駐服務:row 與 statement 兩個層級都支援,並提供 OLD/NEW 轉移表,用在稽核與增量同步上格外合適。
SQL 端的新東西
這一批新增的語法走的都是實用路線。向量相似度搜尋可以用 APPROX NEAREST join,把 top-k 寫成單一 join 子句;INSERT、UPDATE、DELETE、COPY 現在能放進 CTE,讓資料搬移成為管線中的一步;schema 支援巢狀;變數多了 $x 這種寫法;JSON 總算可以原地修改,json_set、json_insert、json_replace、json_remove 一應俱全;遞迴 CTE 引進 USING KEY 聚合,迭代演算法因此能用純 SQL 寫出來。再加上 VARIANT 型別,半結構化資料不需要事先拆成欄位,就能直接進庫查詢。
引擎裡的三項大工程
第一項是非同步 I/O。整個引擎改用非同步存取,由 Parquet 打頭陣,CSV 與自家格式隨後跟上,另外還有非同步的 Parquet 寫入,以及 MMAP、DIRECT_IO 兩種模式。I/O 層自此能與查詢層各自擴展,跑在物件儲存上的遠端查詢受益最深。
第二項是新解析器。DuckDB 不再使用 PostgreSQL 衍生的舊解析器,轉而採用自行開發的 PEG-based 解析器:擴充套件能直接掛進文法,錯誤訊息會附上精確的原始碼位置,設計上也以相容舊語法為原則。團隊在 8 月 20 日另外發表一篇文章詳細說明。
第三項是儲存格式 2.0。欄位 metadata 改為懶載入,開啟寬表的速度更快;DICT_FSST 字串壓縮預設開啟;刪除紀錄佔用的空間更少;讀取時的損毀驗證則嚴格許多。ICU 也整個移除,時區、曆法與排序都改用內建實作,IANA 時區資料壓縮到約 45 kB,微基準跑起來還快了 2.2 到 2.6 倍。
效能方面,遞迴 CTE 引擎經過重寫,百萬邊圖上的單源可達性查詢由 4.90 秒縮短到 0.12 秒,約 40 倍;planner 也懂得利用 DuckLake、Iceberg 與 Hive 的分割,分區裁剪的範圍大幅擴張。
對資料團隊的意義
三個判斷。第一,DuckDB 正從「分析師筆電上的工具」長成可以部署的服務,以往拿 PostgreSQL 硬撐的內部儀表板與 agent 後端,如今多了一個更輕的選項。第二,儲存格式與 C API 都屬於大改,升級前先在測試環境跑一遍,舊檔案與自行維護的擴充套件都會受到影響。第三,重點不在記住十項功能,而在記住方向:DuckDB 想進駐你系統的每一層——筆電、物件儲存,以及如今的伺服器。
