description: "面向部署方与维护者的 SQLite 会话持久化说明,用于选择、配置或排查这个可选启用的分片行后端。"
English | 中文
dsh-session-persistence-sqlite 是 SessionPersistence 服务的可选存储后端:它不按会话各留一个文件,而是把所有会话的持久事件日志统一保存在同一个 SQLite 数据库中。它与 JSONL 后端提供完全相同的逻辑 SessionEvent 流,因此选择它不会改变 agent loop、模型或回放的任何行为——打包、压缩与恢复都是存储内部细节。仅当单一可查询数据库适合你的部署时才选择它;任何已发布的组合都不会默认启用它。这是预发布提供方:它拒绝而非迁移不属于自己的数据库文件,而且其同步 Node SQLite 驱动会在读写时阻塞 JavaScript 线程。设置、容量评估与迁移指引在前;实现内部细节放在下方可折叠的开发者章节中。
当组合需要由 SQLite 支撑的持久会话、且可以接受进程本地的同步数据库驱动时,挂载此提供方。常用路径是显式的:加载会话服务、挂载提供方,然后给出数据库路径。
当本地部署受益于一个可查询数据库、而非每会话一个独立文件时,选择此后端。当消费方需要按会话产物时,请选择 JSONL 后端:本提供方的 locate(meta) 返回 undefined,不支持原始产物,也不暴露任何单会话文件。高并发服务在采用前还应考虑同步 SQLite 与压缩工作。
打包布局以部分 SQLite 本地延迟换取更小的可查询数据库。现有的 501 会话对比测量的是 schema 19,而不是 schema 20;该布局占用 233.18 MB,SQLite 对比基线占用 438.31 MB,压缩 JSONL 占用 148.15 MB。全量写入约比 JSONL 快 2.3 倍,后缀读取也仍快得多;完整读取与 fork 则略慢于 JSONL。方法、完整指标与取舍由持久化延迟与 page size 决策记录。
磁盘成本换来的是结构化、可查询的会话历史视图:外部工具可以用 SQL 分析 sessions 与 events,按本提供方的方式解码物理行——这是内置全文搜索等功能的天然基础。
先加载会话服务,再用数据库路径挂载提供方。除非位置允许依赖进程工作目录(相对路径从该目录解析),否则请使用绝对路径。:memory: 可用于进程内数据库,其内容随进程消失。
- name: '@deepseek-ai/dsh-session'
- name: '@deepseek-ai/dsh-session-persistence-sqlite'
config:
path: /absolute/path/to/sessions.db
| 字段 | 默认值 | 含义 |
|---|---|---|
path |
必填 | SQLite 数据库路径,或 :memory: |
journalMode |
wal |
持久 journal mode:wal、delete、truncate 或 persist |
busyTimeoutMs |
5,000 |
等待另一连接锁的最长同步时间 |
preparedSessionCacheSize |
5 |
为恢复复用而保留的冷会话准备结果数量 |
writeBatchMaxDelayMs |
200 |
实时事件的固定聚合窗口,单位为毫秒 |
生成的配置目录是每个受支持字段及其 JSDoc 的穷尽式真源。
没有内置迁移工具:JSONL 与 SQLite 是两个独立存储,没有任何机制在两者之间复制会话。由于两个后端实现相同的逻辑约定,你可以直接用持久化 API 迁移会话——在 JSONL 侧读取,在 SQLite 侧写入。每个组合只有一个后端服务于 ctx.sessionPersistence,因此两步请分两次运行或分两个进程执行:
// Export — run against the JSONL composition, per session id:
const { meta, events } = await ctx.sessionPersistence.load(id)
// Import — run against the SQLite composition, per exported session:
await ctx.sessionPersistence.create(meta)
await ctx.sessionPersistence.append(id, events)
用 list() 枚举已物化的会话。导出的事件 seq 从 0 开始连续,因此 append 可以一次性按序写入新会话;load 会先在源端提交所需的冷修复,导出的日志因此是平衡的。请把迁移当作一次性切换:确认导入的会话可以加载后,再把组合切换到 SQLite 提供方;之后继续写旧 JSONL 根目录会让两个存储分叉。
全新数据库直接初始化为 schema 版本 20,并使用 64 KiB page。已有文件不会被重新调参:任何其他版本、外来应用标识、无版本的非全新 schema 或意外 schema 对象,都会在任何数据暴露或变更之前被拒绝。本预发布提供方不提供迁移。每条语句和固定 pragma 都来自 resources/sql/ 下打包的 .sql 资源,运行时的值以 SQLite 参数绑定,包代码从不拼装查询文本。
每个连接都会禁用 SQLite trusted schema 与内存映射 I/O、验证所请求的 journal mode,并固定 synchronous=FULL,保证成功返回的追加在操作系统崩溃或断电后依然持久。在 POSIX 上,数据库父目录和文件必须属于当前用户,父目录不得允许组或其他用户写入,文件也不得授予任何组或其他用户权限;Windows 还会拒绝符号链接和非普通文件,ACL 限制则由部署方负责。路径与所有权失败会拒绝插件初始化;Node 的 SQLite 驱动在首次持久化操作时才延迟加载。普通 create 会保持惰性直到首次 append,而 ensureMaterialized 会写入一条没有事件行的会话元数据记录。
当包级约定不够用时阅读以下页面。它们从共享持久化模型逐步进入穷尽式配置,以及物理布局背后的决策证据。
没有 SQLite 专有内容。恢复会还原与 JSONL 后端相同的逻辑事件和派生消息;物理打包标签永远不会进入提示词、工具、回放或实时 session/event 投递。
实时请求 token 为零。恢复只为保留的逻辑历史和当前请求信封消耗 token。
物理打包不会改变请求前缀。提供方缓存复用取决于重建历史、当前信封与模型路由,与其他持久化后端完全相同。
这些限制说明本提供方何时不合适,或何时需要特别的运维注意。它们是当前包约束,不是通用 SQLite 对比或任务积压。
busyTimeoutMs。events.type(text-chunks、reasoning-chunks、tool-call-chunks)不是逻辑事件类型;受支持的消费方通过本提供方读取。