Skip to content

SonnetDB 4.0.0

Latest

Choose a tag to compare

@maikebing maikebing released this 26 Sep 18:02
· 102 commits to main since this release

SonnetDB 4.0.0:完善 SQL 与多模型协作,强化部署和恢复边界

SonnetDB 4.0.0 围绕应用接入中的几个实际问题展开:SQL 能否表达业务查询,插入和更新能否返回准确的生成值,客户端切换连接方式后能否保持相同结果,以及部署、传输和恢复过程能否给出明确的状态。本次主版本更新在既有多模型引擎上,重点完善关系 SQL、ADO.NET 写入与元数据、向量更新、语义图片处理和发布验证。

SonnetDB 继续基于 C# / .NET 10,提供嵌入式和独立 Server 两种使用方式。时序、关系表、键值、JSON 文档、全文检索、向量检索、对象存储、消息队列和原生属性图共享引擎与管理入口,同时保留各自的数据语义。原生属性图仍为 Graph Beta;这一名称不表示外部语义、容量和生产门槛已经通过。

文稿状态:4.0.0 候选发行说明,更新于 2026-09-27。 本文汇总相对已发布 3.1.0 的主要变化。正式发行仍需满足发布门槛,完成 v4.0.0 标签对应的发布流程、NuGet.org 包、GitHub Release 和发布后复验。文中的候选核验结果有明确的提交身份;长期和现场验收状态见文末。

1. ✅ 关系 SQL:覆盖更多业务查询

4.0.0 扩展了关系查询的表达能力,减少应用为常见数据处理而自行拆分查询、拼接结果的需要:

  • CTE 与有界递归查询:支持非递归 WITH、显式输出列名,以及单个递归 CTE 的 WITH RECURSIVE。递归查询设有深度、候选行、累计行数和估算内存限制,超限明确报错。
  • 关系表窗口函数:ROW_NUMBER、COUNT、SUM、AVG、MIN、MAX 支持 OVER (PARTITION BY ... ORDER BY ...),可用于分组编号和累计统计。
  • 更多连接与集合运算:关系表补齐 RIGHT JOIN、FULL JOIN、CROSS JOIN;完善 UNION ALL、INTERSECT、EXCEPT 的重复值、NULL、类型检查和运算优先级。
  • 联接更新与插入查询结果:支持关系表 UPDATE ... JOIN、UPDATE ... FROM,并完善 INSERT ... SELECT 的源快照、精度、资源预算和整句失败行为。
  • 精确类型和常用表达式:增加 DECIMAL / NUMERIC、TIME / TimeOnly,完善 CAST、字符串与日期函数、聚合 DISTINCT、整数按位运算、BETWEEN、ILIKE 和 JSON 标量/数组查询。

SQL 类型与结果元数据同步得到加固:INT 保持有符号 Int64 语义,越界运算明确失败;支持的 DECIMAL 路径保持 System.Decimal 精度,Frame v2 增加精确编码。空结果和全 NULL 列也能保留声明类型,减少客户端依赖首行数据猜测类型的情况。

这些能力按模型分别定义。关系表窗口函数当前不接受显式 ROWS / RANGE frame,排序累计聚合存在大分区性能限制;measurement 不获得关系表的外连接或完整窗口能力。关系表 VECTOR / GEOPOINT 列和 SELECT FOR UPDATE 仍明确拒绝,乐观并发可使用 ROWVERSION。完整语法与限制见 SQL 参考。

2. ✅ 写入与 ADO.NET:统一生成值、返回行和事务结果

UPSERT 与远程事务

关系表新增 INSERT ... ON CONFLICT ... DO NOTHING 和 DO UPDATE SET ... [WHERE ...] [RETURNING ...]。冲突目标可以是主键或唯一索引,excluded.column 引用待插入值;更新条件为 false 或 NULL 时,不写入、不增加影响数,也不产生返回行。

例如,按设备主键插入或更新状态,并取得本次写入结果:

CREATE TABLE device_status (
    id INT,
    status STRING,
    version INT ROWVERSION,
    PRIMARY KEY (id)
);

INSERT INTO device_status (id, status)
VALUES (1, 'online')
ON CONFLICT (id) DO UPDATE SET status = excluded.status
RETURNING id, status, version;

新 Server 的轻事务会话支持跨 ADO 调用读取实际待提交的 DO UPDATE ... RETURNING 结果,并提供提交、回滚及终态查询。会话绑定凭据与数据库,有租约和容量限制。会话状态仍属于单个 Server 进程,多实例部署需要会话亲和路由;重启后的未知提交结果不能当作普通失败直接重试。

UPDATE ... RETURNING 与 DELETE ... RETURNING 也完善了行版本校验、目标行影响数、空结果元数据和远程事务行为。

INSERT ... RETURNING(GH-Issue #197)

关系表 INSERT ... RETURNING 固定以下合同,供 ADO.NET 和 FreeSql 等 ORM 的 identity、插入实体及批量插入映射使用:

  • VALUES 多行按输入顺序返回;INSERT ... SELECT 跟随源查询产出的顺序,要求确定顺序时应在源查询显式指定 ORDER BY。RETURNING 列顺序与声明一致,RETURNING * 按表 schema 顺序返回。
  • AUTO_INCREMENT、ROWVERSION 和列默认值在返回行中已经生成。这里的生成列仅指引擎已支持的自动生成值;任意计算生成列表达式尚不支持。
  • GetName、GetFieldType 和 GetSchemaTable 在第一次 Read 前即可获得声明元数据,空结果也保留列名、类型、可空性、主键、自增及 ROWVERSION 属性。SQL INT 对应 CLR Int64;SQL NULL 的 GetValue 返回 DBNull.Value。
  • 重复主键(包括复合主键)使用稳定错误码 table_unique_violation,整条批次失败,不留下部分插入。嵌入式通过 TableConstraintException.ErrorCode、远程通过 SndbServerException.Error 读取错误码。
  • 事务内可以读取待提交的返回值;回滚后不保留插入行。已经返回的自增值不代表事务已经提交,也不承诺回滚后回收自增序号。
ADO.NET 方法 非空结果 空源批次
ExecuteScalar / ExecuteScalarAsync 第一行第一列;其余插入仍执行 null
ExecuteReader / ExecuteReaderAsync 全部返回行;读完后的 RecordsAffected 为实际插入数 保留 schema 的空读取器,RecordsAffected = 0
ExecuteNonQuery / ExecuteNonQueryAsync 实际插入数,与生成 ID 无关 0

同步、异步和参数化调用遵循相同合同。

连接协议与版本组合

客户端 / Server 组合 可依赖的范围
4.0.0 嵌入式 上述完整合同,以发布包验收为准
4.0.0 客户端 + 4.0.0 Server,rest / auto REST SQL / NDJSON 的完整合同
4.0.0 客户端 + 4.0.0 Server,frame-http2 写入通过同一 HTTP/2 连接回落 REST SQL / NDJSON;完整 ADO 合同相同
3.1.0 客户端 + 新 Server,或新客户端 + 3.1.0 Server 只保留经兼容检查的旧返回值、顺序、影响数;不能依赖完整声明元数据合同
直接调用原生 SQL Frame 查询端点执行 INSERT 拒绝写入,返回 bad_request;不属于 DML 写入通道

依赖完整 ExecuteIdentity / ExecuteInserted 合同的 ORM 应同时升级客户端包与 Server。包版本或连接方式本身不能补全旧 Server 缺失的元数据。

已发布的 3.1.0 包含早期 INSERT RETURNING 实现,但不提供上述完整跨连接合同和关系表 UPSERT 合同。第三方 ORM 的适配与发布仍应以各自版本声明为准。

3. ✅ 向量与语义图片:更新一致性和可恢复处理

measurement 的 VECTOR FIELD 现在支持有界、参数化更新。更新值参与 raw、SQL、聚合和 KNN 读取,并与删除、保留策略、DROP、备份恢复和重开过程协同。当前仅更新已有 VECTOR 点,WHERE 限于 TAG/time;单次最多 256 行,存活替换记录最多 4,096 条和 128 MiB 估算字节量。它不扩展为关系表 VECTOR 列,也不承诺任意规模的原地向量更新。

语义对象桶回填在内部页预算耗尽时保存已完成对象的游标和累计进度,后续可以继续处理;修复了末项入队后取消导致 HTTP 500 的问题。向量精确扫描的适用 Top-K 路径使用有界候选堆,仍执行完整扫描,结果不依赖近似召回。

图片处理迁移到 SkiaSharp + TiffLibrary,构建和运行不需要供应商账户、商业激活或许可密钥,发布物保留依赖的版权与分发声明。内置图片处理明确支持 PNG/APNG、JPEG、WebP、GIF、BMP、ICO、TIFF 七类,增加损坏输入和像素预算检查。

升级时需要关注图片 embedding profile:本地 SigLIP2 路径使用 :skia-rgba-v1 后缀隔离新的预处理结果,旧向量不会自动混入。对象桶需重新执行 Backfill,直接摄取的图片需重新提交原图;旧 profile 和原始对象保留,历史缩略图仍可读取。详见 图片处理迁移和语义图片检索。

4. ✅ 多模型客户端与管理工具:明确取消、传输和恢复状态

本次继续完善各模型已有的 SDK、Server、CLI 和工作台接口,重点补齐取消传播、请求与响应目标绑定、分页、批量处理和恢复行为:

  • KV:增加命名空间内的快照游标和页字节预算,控制跨 keyspace 的磁盘读取并发。
  • 对象存储:完善分片上传和传输恢复清单;CLI 下载先写入临时文件,校验后替换目标,避免失败留下部分目标文件。没有服务端 SHA-256 时,只报告传输完成。
  • SonnetMQ:修复 retention/tombstone 后的去重索引清理,保留仍可读取消息的去重语义;实例快照与恢复继续使用独立合同。
  • SQL 工作台:显式结果预览会显示截断状态,客户端可读取 SndbDataReader.Truncated;预览上限不等同于服务端执行内存上限。
  • SonnetDB Studio:可选择已有嵌入式数据库目录,由本地 Server 显式挂载;挂载库不会通过 Server 的删除数据库接口被移除。

原生属性图继续提供 Graph Beta 范围内的顶点、边、原生邻接、SQL/PGQ 和管理入口。Graph 的外部对照、固定硬件和长期负载验收仍独立进行;CDC 与流处理也继续按各自成熟度展示,不能从统一管理入口推断所有模型都已通过同一生产门槛。

5. ✅ Copilot、CDC 与订阅:增强已实现的基础能力

Copilot 的 ServerRelay 增强了持久事件日志、页面刷新后的重放、跨实例活跃事件跟随,以及执行者丢失后的确定失败收尾。Unix 上共享 journal 的锁文件保持稳定,避免不同进程锁住不同文件而失去互斥。失败重放不会透明重跑模型或工具调用。

BrowserDirect 提供 OAuth/PKCE 获取入口,StudioNative 补齐凭据存储、短期 token、只读 typed MCP continuation 和取消清理。这些实现已有本地合同与自动化验证;真实 IdP、部署双网和模型质量/成本仍需独立验收。

CDC 新增版本化事件与有界 append/replay/ack spool;流订阅支持 watermark、迟到策略、背压、显式 ACK 和文件 checkpoint。这些是已交付的基础切片,尚不等于完整复制拓扑、冲突解决或 exactly-once。参见 CDC 合同、订阅合同与能力成熟度。

6. ✅ 部署与发布:安全的初始网络配置和可核对的产物

Server/Studio bundle 和安装包内置 Server 的 HTTP/Frame 默认仅监听 loopback,MQTT、CoAP/DTLS、Line Protocol UDP 和 Modbus 等额外入口默认关闭。Docker Compose 的默认主机端口也限制在 loopback。需要远程访问时,应先完成本机初始化、配置每部署唯一凭据,再显式开放监听地址和端口。

发布预检现在把源码提交、候选版本、NuGet、平台 bundle、连接器和合同验收产物绑定在一起,并检查文件库存、SHA-256 和必需原生文件。旧版本产物、较新失败、未完成的重跑,以及参考服务实际未执行的 Parity 报告,都不能作为正式发布通过的依据。

NativeAOT 与 source-generated JSON 继续作为相应生产路径的要求;Server 和连接器按各自 RID 验证原生发布与入口。EF Core、Studio 和其他外围组件仍遵循各自部署要求,不统一宣称所有包均为 NativeAOT。产物组成与启动方式见发布与打包。

7. ⚠️ 主版本兼容性与升级建议

主版本兼容性

4.0.0 候选沿用发布就绪审计的主版本方案:与 3.x 相比,公开 TokenKind 的部分数值、部分 SQL AST 与文档索引类型的构造函数和 Deconstruct 签名已经变化。升级时需要重新编译相关消费者并检查直接依赖这些 API 的代码。此方案不声明与 3.x 的二进制 API 兼容;原有 3.x 包兼容门禁继续保留。

#197 的 INSERT RETURNING 收口本身不改变持久化二进制格式;整个 3.1 → 4.0 升级还涉及 DECIMAL/TIME 等关系 schema 演进,不能据此前一句推断全部文件都可由旧版本回读。TIME 的 schema format v10 支持读取旧 schema,不代表旧 Server 能读取新类型和新 schema。

建议按以下顺序升级:

  1. 备份并验证恢复:在维护窗口按备份文档保存数据库并验证;Server 的 SonnetMQ 位于实例级 .system/mq,需要按实例方案单独处理,单库备份不包含它。
  2. 同步升级客户端与 Server:重新编译直接依赖公开 API 的程序,验证参数类型、空结果元数据、RETURNING、自增键和事务行为。依赖完整新合同的应用不能只升级其中一端。
  3. 核对网络与身份配置:适配新的 loopback 默认值;多实例远程 SQL 事务配置会话亲和,并演练提交结果未知时的处理。
  4. 重建需要迁移的语义索引:本地 SigLIP2 图片按新 profile 回填;旧 profile 可保留用于回滚。
  5. 用真实工作负载复验:检查资源限制、查询结果、恢复和客户端协议协商,再安排切换。回退使用升级前验证过的备份,不假定旧二进制可直接打开升级后的所有文件。

原生 SQL Frame 查询端点继续只读。新客户端在 auto 模式遇到旧 Server 时可按协议合同回退 REST;强制 Frame 的新类型/版本要求不能靠静默降精度满足。

8. 🧪 候选验证与尚未完成的验收

发布验证

eng/verify-insert-returning-package.ps1 从待发布 feed 安装精确版本,隔离 NuGet 缓存并比对安装包 SHA-256;同一消费者依次验证嵌入式、REST、Auto 和精确 HTTP/2 写入回落。-VerifyPublishedBaseline 下载官方 3.1.0 Server bundle 并核对公开 SHA-256,再检查新旧客户端与 Server 的三个协议组合。旧版本兼容结果单独记录为 legacy-values-only。

Publish workflow 在 Windows/Linux 两个平台生成并验证 NativeAOT Server,所有协议检查通过后才推送同一批 NuGet 包并创建 GitHub Release。workflow_dispatch 可执行候选验证,不推送包。各次 result.json、消费者及 Server 日志保存在 insert-returning-contract-<version>-<rid> artifact。候选本机证据见 #197 包验收记录。

2026-09-26 候选提交 67d61f307d333743b50dce82b043291f141ec950 已完成十二类工作流、十四次实际运行的线上核验。以下结果仅属于该提交,不自动成为后续提交或正式标签的通过证据:

核验项目 候选结果 可依赖的范围
Windows / Linux 完整 CI 6,692 / 6,692;6,634 / 6,634,均无失败或跳过 该提交的自动化回归
三个架构 NativeAOT 通过,日志无编译器及 IL/AOT 警告 被验证的原生发布路径
Parity full 51 场景中 49 通过、2 跳过、0 失败;十种必需参考服务全部实际执行 当前场景集合的对照;TPCC 与 Holt-Winters 保留跳过,外部 Graph 对照未执行
Windows / Linux 包合同 两个平台各 10 / 10 通过 候选包、官方 3.1.0 基线及新旧端组合合同
连接器与 Docker 候选预检通过 对应 RID 的原生入口、镜像启动及管理页面;不表示真实 AI provider 全部健康

可追溯的线上记录:完整 CI、Parity、包合同、连接器、Docker。

⏸️ 自 2026-09-27 起,七天 scheduled Parity 为非阻断观察项。 窗口不足、历史运行失败或观察证据获取失败继续如实记录,不阻断正式发布;M20 的连续七天观察目标仍未完成。正式发布仍须通过同一提交、同一候选版本的十二类工作流,以及当前候选 light/full Parity 的原始 artifact 校验;这些必需证据缺少、未完成或失败时仍会阻断发布。

历史核验结果保持不变:上述提交 67d61f307d333743b50dce82b043291f141ec950 在 2026-09-26 的严格原始证据判定为 0/7,按当时政策记录的整体发布状态为 NOT_READY。新政策不将该观察结果改记为通过,手动 light/full 成功也不替代连续七个 UTC 日期的 scheduled 结果;后续发布判断应使用绑定新候选提交与版本的核验报告。

168 小时混合负载、固定硬件百万/千万规模、干净 Windows/WebView2 安装升级卸载、真实模型质量与成本、现场双网和生产 HA 继续独立验收。托管缩规模、包构建和本地自动化通过,不将这些事项改记为完成。

项目地址:IoTSharp/SonnetDB。正式产物以 GitHub Releases 和对应版本包为准;完整变更见 CHANGELOG。