SonnetDB MQ 的两个作用域:数据库权限与实例 Snapshot

SonnetDB MQ 的两个作用域:数据库权限与实例 Snapshot

SonnetDB 的 SonnetMQ 同时有数据库资源树中的 database + topic 逻辑身份,以及实例级 .system/mq 持久化边界;本文用这两个作用域组织权限、快照和恢复检查清单,避免把单库备份误写成整个消息实例的恢复方案。

SonnetDB MQ 的两个作用域:数据库权限与实例 Snapshot

AI 主题示意图,并非实测截图。

本文按本地源码提交 dbc8178988a0293ed67d24e6f70b78b970465aa0 和 SonnetDB 的当前工程文档核查。GitHub Release 与 NuGet 包的当次版本核验会在排队前写入发布账本;下文不把较新的源码合同自动等同于已发行包。文中的 API 片段说明当前源码与测试覆盖的边界,不是已验证的固定硬件、远程服务、跨节点、掉电恢复或长期生产运维结果。

1. 先把两个作用域分开

SonnetMQ 在数据库资源树中以 database + topic 定位:同名 Topic 在不同数据库中是不同逻辑资源,当前 bearer token 的数据库 grant 决定该请求能否 browse、publish 或 ack。管理端页面和客户端 URL 应带上数据库上下文,而不是把一个裸 topic 当成跨库全局名称。

与此同时,Server 的物理 MQ 数据位于实例数据根目录下的 .system/mq。它保存 Topic 日志、消息头、消费者组 offset 与 retention 记录,是实例级持久化边界。这个差别可以用下面的表快速检查:

问题 应落在哪个作用域 不能推出的结论
谁可以对 orders publish/ack 数据库 + Topic 与当前 token/grant 获得某个数据库 grant 不代表可读另一个数据库的 Topic
消费者组 offset、消息头和 retention 实例 .system/mq 单库备份已覆盖 MQ 日志
操作 UI 的危险写确认 当前数据库权限,再经过审批/确认 前端确认可绕过服务端鉴权
恢复演练 数据库恢复点与 MQ 实例 snapshot 各自核验 两者天然原子、自动保持同一时间点

当前管理工具文档明确:危险写、导入、删除和 rebuild 必须经 WriteApprovalPanel、dry-run 或显式确认之一;这只是操作界面的保护层,权限仍由 Server 的 bearer token 和数据库 grant 决定。ReadOnly token 不应 publish 或 ack;ReadWrite token 的范围也仍须按数据库确认。

相关合同可从 SonnetMQ 高层客户端、管理工具说明 和 ROADMAP 的九模型恢复边界 交叉核对。

2. 实例 snapshot 覆盖什么

当前 SonnetMqStore 的实例 snapshot manifest 包含全局 Topic 日志、消息头、消费者组位点和 retention 记录。创建快照时,源码会阻断 publish、ACK、NACK、offset reset、retention 与新 Topic 创建,随后 flush 并校验每个快照文件;恢复时先验证 manifest 与文件 SHA-256,再在目标目录完成 staged restore。

下面是嵌入式代码层的最小形状。它用于说明调用面,不是可直接替代生产维护窗口的通用脚本:

using System;
using SonnetDB.Core.Mq;

using SonnetMqStore store = SonnetMqStore.Open(new SonnetMqOptions
{
    Path = @"D:\sonnetdb-data\.system\mq",
});

SonnetMqInstanceSnapshotResult created = store.CreateSnapshot(
    @"D:\backups\sonnetmq-2026-10-26");

SonnetMqInstanceSnapshotManifest manifest =
    SonnetMqStore.ReadSnapshotManifest(created.SnapshotDirectory);

// 在隔离目标目录验证并恢复,而不是直接覆盖正在运行的实例目录。
SonnetMqStore.RestoreSnapshot(
    created.SnapshotDirectory,
    @"D:\restore-staging\.system\mq");

Console.WriteLine($"files={manifest.Files.Count}");

仓库的 SonnetMqInstanceSnapshotTests 覆盖了目录与单文件模式的创建/恢复,并检查消息、header、消费者 offset 和后续 publish 的一致性。这是源码测试覆盖,不是本篇执行过的恢复演练。务必先在隔离目录读 manifest、核文件 hash、重开 store 并对照一组 Topic/consumer group,再决定是否切换实例目录。

3. 数据库恢复和 MQ 恢复怎样组合

当前合同没有把数据库目录恢复与 .system/mq 快照声明为一个原子事务。因此恢复 runbook 应保留两个独立的时间点和一条外部副作用对账路径:

  1. 记录数据库备份标识、MQ snapshot manifest 路径、创建时刻、实例版本和计划的停写窗口。
  2. 停止或隔离所有能 publish、ack、nack、reset offset 与修改 retention 的入口;不要在活动目录上复制 .system/mq 来代替 snapshot。
  3. 分别恢复数据库目录和 MQ snapshot 到 staging 位置,先验证数据库可打开,再用 ReadSnapshotManifest、文件 hash、Topic 统计和 consumer offset 核验 MQ。
  4. 选择一个 database + topic + consumerGroup 对照清单,记录预期 offset、可见消息和 retention 下界;恢复后只把同一清单中的实际值与预期比较。
  5. 对外部处理器、HTTP 回调或其它副作用保留幂等键和人工对账。MQ 的至少一次、未知外部结果和有限 retention 不能由“两个目录都恢复了”自动消除。

若写入或恢复请求的结果在网络或进程故障后无法确认,应先只读检查原目录、manifest、审计记录与已提交 offset,而不是盲目重做同一写操作。这个原则同样适用于快照上传、切换目录和外部消费者启动。

4. 一个可审阅的恢复前后检查表

阶段 必须记录 可判定结果
前置 数据库备份 ID、MQ manifest、实例目录、停写确认 两个恢复对象是否都可定位
staging 恢复 manifest 格式、逐文件 SHA-256、目标目录、重开结果 snapshot 文件是否完整且可读
逻辑核对 database + topic + consumerGroup、next offset、retention 边界 恢复后是否符合本次明确选择的对照点
业务核对 外部副作用幂等键、待处理记录、人工签核 是否仍有未知外部结果需要交接

这张表刻意没有 RPO、RTO、可承载消息量或吞吐数字。当前路线图仍将“MQ 实例 snapshot/restore 与数据库恢复组合、offset/任务/checkpoint 对账、公开 RPO/RTO 与非原子边界”列为 M36 的独立证据项;单库备份不能替代该项。

5. 支持边界与下一步

已在源码合同中看到的能力包括:实例 MQ snapshot manifest、SHA-256 核验、staged restore、消费者组 offset 和 retention 记录;管理面也已声明 Topic 浏览、lag/retention/DLQ 诊断和危险写确认。它们不足以证明生产恢复已经验收。

本篇没有运行数据库备份、MQ restore、远程 Server、固定硬件、跨进程 kill/reopen、外部消费者、性能、RPO/RTO 或长期稳定性测试。Graph、真实模型和其它九模型证据也不在本篇范围。实际部署应先把本地恢复演练、版本兼容、权限矩阵和外部副作用对账单独记录,再决定是否扩大到现场门禁。

参考


关注我们,扫码进群沟通

欢迎关注我们,扫码加入微信或 QQ 交流群,一起交流技术实践,分享使用经验和问题反馈。

微信交流二维码

微信交流二维码

QQ 交流群:IoTSharp,群号 63631741

IoTSharp QQ 交流群二维码,群号 63631741

请扫码并关注我们,进群沟通。若二维码暂时无法使用,可通过 QQ 群号 63631741 搜索加入。

posted @ 2026-10-27 03:32  IoTSharp  阅读(5)  评论(0)    收藏  举报