在网上看到韩国公司开发的一款GooseDB,DuckDB™ 的功能扩展分支,具有服务器/客户端、多会话和并发写入支持,使用 PostgreSQL 有线协议,但它是Freeware而不是开源,所以让DeepSeek实现之。
首先把readme页面发给他翻译,并让他据此写一个设计方案,看上去头头是道。
GooseDB:为协同数据分析而强化的DuckDB
GooseDB是基于DuckDB的强大功能扩展版本,旨在将协同数据分析提升至新高度。
在继承DuckDB卓越速度与分析能力的基础上,GooseDB针对现代数据工作流引入了关键增强功能,
包括服务器/客户端架构、多会话支持和并发写入能力,同时全面兼容强大的PostgreSQL有线协议。
核心特性:
• 服务器/客户端架构:GooseDB将DuckDB升级为真正的客户端-服务器数据库,允许多用户同时连接并交互同一数据库实例,
为协同数据探索与分析开辟了新可能。
• 多会话支持:通过支持多并发会话,团队可并行处理同一数据,优化工作流程并促进协作。
• 并发写入能力:与原生DuckDB不同,GooseDB支持并发写入,在保持高性能的同时实现实时数据更新与注入,
这对需要持续数据更新的应用至关重要。
• PostgreSQL有线协议:采用广泛使用的PostgreSQL有线协议,确保与现有数据库工具、客户端及库生态系统的无缝集成,
降低了熟悉PostgreSQL用户的学习成本。
• 增强的性能:保留DuckDB在分析查询方面的卓越性能,即使处理复杂数据集也能提供极速响应。
• 与现有DuckDB生态无缝集成:保持与现有DuckDB API及数据格式的兼容性,用户可轻松迁移现有项目。
使用优势:
• 强化协作:支持团队实时协同进行数据分析项目。
• 改进数据管理:通过并发写入支持简化数据注入与更新流程。
• 简化集成:利用PostgreSQL协议与现有工具无缝对接。
• 提升效率:借助更快的查询性能和协作工作流提高生产力。
• 可扩展性:通过改进的并发与服务器架构处理更大数据集和复杂工作负载。
适用场景:
• 协同数据科学:助力数据科学团队共同开展数据探索、模型开发与分析。
• 实时数据分析:为需要即时洞察的应用提供实时数据注入与分析能力。
• 商业智能:为业务用户提供强大的协同数据分析与报告平台。
• 数据仓库:构建支持并发写入和大数据集的高性能数据仓库。
软件设计方案(基于技术文档特性提炼)
1. 架构设计
- 客户端-服务器模型:采用多线程服务器架构,通过TCP/IP协议监听客户端连接,使用PostgreSQL有线协议实现通信规范化
- 连接池管理:实现会话管理器(Session Manager)维护多用户连接状态,支持会话隔离和资源分配
- 并发控制层:
- 写操作:通过行级锁+多版本并发控制(MVCC)实现并发写入与数据一致性
- 读操作:支持无锁快照读,兼容DuckDB原有向量化执行引擎
2. 核心模块
┌─────────────────────────────────┐
│ Client Applications │
└─────────────────────────────────┘ │
┌─────────────────────────────────┐
│ PostgreSQL Wire Protocol Layer│
│ (协议解析/消息序列化) │
└─────────────────────────────────┘ │
┌─────────────────────────────────┐
│ Session Manager │
│ (会话状态/查询路由) │
└─────────────────────────────────┘ │
┌─────────────────────────────────┐
│ Concurrency Controller │
│ (锁管理/MVCC协调) │
└─────────────────────────────────┘ │
┌─────────────────────────────────┐
│ DuckDB Execution Engine │
│ (优化器/向量化执行) │
└─────────────────────────────────┘ │
┌─────────────────────────────────┐
│ Storage Layer │
│ (数据持久化/索引管理) │
└─────────────────────────────────┘
3. 关键技术实现
- 协议适配层:基于libpq或自定义实现PostgreSQL报文解析,兼容常用SQL命令和扩展命令
- 内存管理:扩展DuckDB的内存分配机制,支持多会话内存隔离与全局内存配额
- 持久化策略:
- 数据文件格式保持与DuckDB兼容
- 预写日志(WAL)支持并发写入崩溃恢复
- 扩展语法支持:增加服务端专属命令(如SHOW_SESSIONS)并通过协议层封装传输
4. 性能优化方向
- 连接建立:采用异步I/O模型处理高并发连接请求
- 查询处理:复用DuckDB向量化执行引擎,增加分布式查询规划器扩展
- 缓存机制:实现服务端结果集缓存,支持重复查询快速响应
5. 安全设计
- 基于PostgreSQL协议的SSL加密传输
- 角色权限管理系统(兼容DuckDB原有权限模型)
- SQL注入防护通过协议层参数化查询实现
此设计方案聚焦协议兼容性、并发扩展和生态集成三大核心目标,在保持DuckDB性能优势的同时实现服务化能力升级。
于是,先让他实现第一部分
请用duckdb C API实现一个Demo。先实现客户端-服务器模型:采用多线程服务器架构,通过TCP/IP协议监听客户端连接,使用PostgreSQL有线协议实现通信规范化,不做别的
他给出了一个c服务端程序和一个python客户端程序。我的机器安装psycopg2失败,于是直接用postgresql客户端psql连接。
他的知识库里的duckdb版本较旧,说是0.9.0+, 其实有的数据结构还是更旧的。
比如duckdb_result结构,libduckdb 0.9.2的定义是这样的:
typedef struct {
#if DUCKDB_API_VERSION < DUCKDB_API_0_3_2idx_t column_count;idx_t row_count;idx_t rows_changed;duckdb_column *columns;char *error_message;
#else// deprecated, use duckdb_column_countidx_t __deprecated_column_count;// deprecated, use duckdb_row_countidx_t __deprecated_row_count;// deprecated, use duckdb_rows_changedidx_t __deprecated_rows_changed;// deprecated, use duckdb_column_ family of functionsduckdb_column *__deprecated_columns;// deprecated, use duckdb_result_errorchar *__deprecated_error_message;
#endifvoid *internal_data;
} duckdb_result;
而libduckdb 1.3.2变成了这样:
//! A query result consists of a pointer to its internal data.
//! Must be freed with 'duckdb_destroy_result'.
typedef struct {// deprecated, use duckdb_column_countidx_t deprecated_column_count;// deprecated, use duckdb_row_countidx_t deprecated_row_count;// deprecated, use duckdb_rows_changedidx_t deprecated_rows_changed;// deprecated, use duckdb_column_*-family of functionsduckdb_column *deprecated_columns;// deprecated, use duckdb_result_errorchar *deprecated_error_message;void *internal_data;
} duckdb_result;
而他就引用了column_count、row_count这些成员。于是替换成了带deprecated_前缀的版本。编译通过了。
服务器端
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:libduckdb
gcc goose2.c -o goose2 -I libduckdb -L libduckdb -lduckdb -lpthread
root@6ae32a5ffcde:/par# ./goose2
GooseDB server listening on port 5432
You can connect using: psql -h 127.0.0.1 -U any_user -d any_db -p 5432
Note: Username and database name are logged but not used for authentication
New connection from 127.0.0.1:34146
Client connected on socket 4
客户端
psql -h 127.0.0.1 -U any_user -d any_db -p 5432
^C
只能显示连接,而不能取到数据。看来需要进一步研究。
经过几轮交互,现在进展到这一步了。
服务端, 其中对应psql连接,PGSSLMODE=disable前是127.0.0.1:58912,后是127.0.0.1:39740
root@6ae32a5ffcde:/par# ./goose3
GooseDB server listening on port 5432
You can connect using: psql -h 127.0.0.1 -U any_user -d any_db -p 5432
Note: Username and database name are logged but not used for authentication
New connection from 127.0.0.1:58912
Client connected on socket 4
已打开DuckDB数据库
已连接DuckDB数据库
Received startup message, length: 8
已读取启动消息
New connection from 127.0.0.1:39740
Client connected on socket 5
已打开DuckDB数据库
已连接DuckDB数据库
Received startup message, length: 87
Connection parameters: user=any_user, database=any_db
已读取启动消息
客户端
psql -h 127.0.0.1 -U any_user -d any_db -p 5432
psql: error: connection to server at "127.0.0.1", port 5432 failed: received invalid response to SSL negotiation:export PGSSLMODE=disable
psql -h 127.0.0.1 -U any_user -d any_db -p 5432
psql: error: connection to server at "127.0.0.1", port 5432 failed: message contents do not agree with length in message type "S"
lost synchronization with server: got message type "i", length 1869479985
又改了一版
gcc goose4.c -o goose4 -I libduckdb -L libduckdb -lduckdb -lpthread
./goose4
GooseDB server listening on port 5432
You can connect using: psql -h 127.0.0.1 -U any_user -d any_db -p 5432
Note: Username and database name are logged but not used for authentication
New connection from 127.0.0.1:39146
Client connected on socket 4
已打开DuckDB数据库
已连接DuckDB数据库
Received startup message, length: 79
Received normal startup message
Connection parameters: user=, database=
已读取启动消息
Message too large: 4207 bytes, buffer size: 4096
Unknown message type: e
客户端
export PGSSLMODE=disable
psql -h 127.0.0.1 -U abc -d def -p 5432
psql (15.13 (Debian 15.13-0+deb12u1), server 14.0)
Type "help" for help.def=> select 1 a;