存储
TIP
数据分三类:数据库中的结构化数据、实例数据目录下的文件,以及凭据。会话是顺序追加的日志,权限是关系型规则表,凭据是需要严格保护的敏感文件,访问模式差异很大,所以分开存储,备份和排查方式也各不相同。
数据库
默认使用 SQLite,数据文件在实例数据目录下。上层只依赖表结构定义,更换数据库驱动即可迁移到其他受支持的数据库。
| 表 | 内容 |
|---|---|
chatluna_conversations | 会话键与元信息 |
chatluna_sessions | 会话日志的索引与分页 |
chatluna_session / chatluna_session_header / chatluna_session_entry | 会话日志的存储实现 |
chatluna_files | 内容寻址的文件(图片、附件) |
chatluna_peers | 路由用到的对端资料 |
chatluna_permission_user | 用户等级 |
chatluna_permission_role | 角色与继承 |
chatluna_permission_rule | 权限规则 |
chatluna_permission_log | 权限判定审计 |
chatluna_config_changes | 配置变更记录 |
chatluna_registrations | 运行时注册信息 |
chatluna_replay_experiments | 轨迹重放的实验记录 |
chatluna_trace_spans | 轨迹 span |
chatluna_usage | 用量明细 |
chatluna_usage_daily | 用量每日汇总 |
chatluna_character_state | 角色状态变量 |
chatluna_schedule | 定时任务 |
chatluna_schedule_run | 定时任务执行记录 |
表由各插件在启用时按需创建。
TIP
看不到某张表,通常是提供它的插件还没启用。
大多数表用自增整数主键,自带业务标识的表用字符串键。索引围绕高频查询设计:会话按会话键与时间戳、用量按日期与模型、权限按动作与主体。
会话日志
会话主表只记录索引与分页游标,正文保存在会话存储中,按追加日志组织:
- 避免全量读取:日志持续增长,全量读取开销很大。
- 高效分页:只需起止位置即可按需截取。
- 轻量维护历史:压缩和分支只是游标层面的位置操作,不修改实际内容。
文件
图片、音频、附件等二进制内容统一存在 chatluna_files 表,按内容哈希去重:同一张图片在多个会话中发送,也只存一份。所以删除消息不一定立即清理文件,物理清理由后台定时任务异步完成。
凭据
API 密钥等凭据不存数据库,而是存在数据目录下的专属 JSON 文件中,目录权限 0700、文件权限 0600。插件配置中只保存引用,如 {$credential: "xxx"},运行时发起调用时才解析为真实密钥。
WARNING
凭据文件是明文 JSON,安全性依赖宿主机的文件权限与主机安全,而不是应用层加密。备份时可以和整个数据目录一起加密,或单独妥善处理。
写入采用「临时文件 + 原子替换」:先在同目录写临时文件,同步落盘,再原子重命名覆盖旧文件。即使中途崩溃也不会留下半截文件。
配置变更与快照
所有配置修改都有记录。部分核心插件(如平台适配器)还支持在每次修改前自动保存快照,误配置时可以回退。快照目录是可选特性,默认不开启。
向量存储
向量服务是纯抽象接口,运行时注册了具体后端才能工作。没有可用后端时调用会明确报错,而不是静默降级为关键词搜索。
迁移
表结构由插件在启动时声明。升级插件时自动补齐新字段,兼容旧数据。
WARNING
跨大版本升级前务必备份。自动迁移通常只处理追加字段这类兼容变更,表结构重构或破坏性调整可能需要按版本指引手动处理。
备份
完整恢复一个实例需要:
- 数据库文件:结构化数据、索引与会话游标。
- 数据目录:凭据、技能、工作区、快照等。
- 配置清单:全局配置与插件启停列表。
冷备份:停止实例 → 完整复制实例目录 → 重新启动。运行中直接复制 SQLite 文件可能因 WAL 或未落盘的缓存得到不一致的数据。
清理与保留
- 用量明细:默认保留 90 天,每日汇总永久保留。
- 轨迹:按会话定期清理,或缩短保留期。
- 文件:按引用计数定期清理无引用的附件。
- 会话:删除会话时级联清理关联的日志。
TIP
磁盘空间不足时,先看用量明细和轨迹,它们增长最快。
诊断
内置的存储诊断会检查:数据库能否正常读写、已注册插件的表结构是否完整、会话日志是否满足追加与游标的不变量、凭据文件路径与权限是否可读。会话级诊断能发现「日志断档」「游标与正文脱节」等一致性问题。
常见问题
数据丢失:确认加载的是正确的实例数据目录,以及实例是否曾因崩溃进入安全模式或在恢复中切换到了备用数据库。
数据库被锁:另一个进程占用了同一个数据库文件。检查是否有残留的旧进程,或同时启动了两个使用相同数据目录的实例。
磁盘增长过快:检查用量明细和轨迹的保留期,以及 chatluna_files 中是否有大量未清理的无引用附件。
凭据读取失败:文件损坏或权限不对。看日志中的读取或解密报错,必要时在管理界面重新保存凭据。
升级后旧数据不兼容:从备份恢复,并按对应版本的发布说明手动迁移或修复。