Skip to content

fix(storage): 加固数据库持久化并修复 Windows 技能目录链接 - #1034

Open
sea1dream wants to merge 2 commits into
iOfficeAI:mainfrom
sea1dream:fix/windows-persistence-reliability
Open

sea1dream wants to merge 2 commits into
iOfficeAI:mainfrom
sea1dream:fix/windows-persistence-reliability

Conversation

@sea1dream

@sea1dream sea1dream commented Oct 21, 2026 •

Copy link
Copy Markdown

问题与目标

针对重启及异常恢复场景中的持久化风险,加固数据库启动、旧库迁移、配置更新和 Windows 文件操作,保留出错时可供检查的数据文件。

Related: iOfficeAI/AionUi#4339

该 issue 记录了重启后模型、CSS、聊天记录不可见,以及主数据库与 WAL 组合后的逻辑不一致。目前没有确定性复现,也没有证明某个 SQLite 竞态、认证失败或本 PR 修复的单一代码路径就是事故根因。 因此这里关联 issue,保留其后续调查状态。

配套 AionUi PR:iOfficeAI/AionUi#4342。

修复内容

数据库与模型配置

  • 启动锁覆盖初始化及明确启用的损坏恢复流程;无法取得锁时返回错误。迁移或系统用户初始化失败时先关闭连接池,再进入后续处理。
  • 重建前完整归档已有 DB、WAL、SHM 和 rollback journal,归档完成后才移除原文件。移除失败时尝试恢复已移除的组件;通过持久化的恢复标记阻止下一次启动接着打开不完整状态。默认不启用破坏性重建。
  • 旧库导入改用只读源连接与 SQLite Online Backup API,纳入已提交的 WAL 内容;快照通过 quick_check 后才发布,不覆盖已有目标。旧目标的孤立日志文件也先保留,不直接丢弃。
  • 提供方局部更新改成单条 UPDATE … RETURNING,按实际写入时的行合并字段,避免并发更新用旧快照覆盖彼此;保留“未传入”和“显式清空”可空字段的区别。

内置 SQLite

  • 在保持 SQLx 0.8.6 / rusqlite 0.32.1 所需 libsqlite3-sys 0.30.1 接口的前提下,编译官方 SQLite 3.51.3 amalgamation。
  • SQLite 官方将 3.46.0 列入 WAL-reset 缺陷影响范围,并在 3.51.3 修复。此升级消除已知版本风险,不构成本次事故归因证据。
  • vendor/libsqlite3-sys/AIONUI-PATCH.md 记录来源、下载哈希、官方 source ID 和核验过的 sqlite3.c SHA3-256。SQLite C 源码保持官方原样;SQLCipher 部分保持包装库原版,本项目没有启用它。
  • 增加集成测试,通过实际 SQLx 连接查询 sqlite_version() 并断言版本至少为 3.51.3,以检测意外链接回旧版本。较大的 diff 主要来自完整 vendor 源码;后续可随 SQLx/rusqlite 协同升级替换此兼容补丁。

Windows 兼容性

  • 技能导入时替换已有目录,用 symlink_metadata 检查链接本身;Windows 目录符号链接/junction(包括目标已不存在的情况)使用非递归 remove_dir 移除链接,保留真实目标目录及文件。
  • 文件树、列表和内容更新事件中的工作区相对路径,在 Windows 统一序列化为 /;绝对路径字段保持原语义,Unix 文件名中的字面反斜杠不被改写。
  • 将扩展 hook、Node 运行时、终端、MCP、项目/侧栏及工作目录测试夹具改成对应平台可执行、可解析的形式;继续检查实际子进程、环境变量、输出、退出码、超时错误、路径边界及最终树状态。
  • 针对 Windows 文件系统事件差异明确断言实际事件及最终状态;调整少量 Unix 专属测试的编译条件,避免 Windows 上只提前返回、实际没有执行断言的测试体。

验证

测试提交:c74eb28488f77392bbfcf3eb8ba4b03973631dac,基于 AionCore v0.2.2(47e66d0);Windows x64,Rust 1.95.0。

  • just push 全部检查成功:migration guard、Cargo fix、Clippy(-D warnings)、format、全工作区 nextest。
  • 9,327 项通过,52 项跳过。原 Windows 基线的 79 个失败项逐项核对均为 PASS;其中两项测试重命名已按 crate、target 和测试名映射核对,52 个跳过项不属于原失败清单。
  • 单独执行工作区文档测试:27 个 crate 文档测试目标完成,0 个可执行示例、1 个既有示例忽略,0 失败。
  • cargo build --release -p aionui-app --bin aioncore -j2 --target-dir target-release 完整优化构建成功。
  • 对该正式可执行文件执行独立临时数据目录验证:真实 HTTP 认证和访问控制、失效技能 junction 重新导入、嵌套路径列表及读写/缓存刷新、父进程退出后的正常关闭、关闭后的完整性检查和合成账号保留均通过。二进制官方 source ID 与新数据库写入版本均确认 SQLite 3.51.3。

为控制本机编译资源,全工作区测试使用 release 依赖缓存,工作区包通过外部 CLI 配置设为 opt-level=0,第三方依赖仍为 release 优化;nextest 使用 16 个测试线程、无测试过滤。上述正式程序构建没有使用该测试配置。测试配置和本机诊断资料未写入仓库。

文件型回归测试覆盖带已提交 WAL 的旧库快照、无效源库拒绝发布、日志归档/恢复中断及并发提供方局部更新;目录链接测试核对目标内容不变。

边界与审阅提示

  • 这是已验证修复分支的两个提交:c421a24(持久化及 SQLite)、c74eb28(Windows 文件操作及测试可移植性)。本次按仓库汇总提交,维护者可分别审阅。
  • 归档/锁/恢复状态检查失败现在会明确阻止启动,需要检查保留的文件;不会静默继续初始化或宣称数据已恢复。
  • 本 PR 不增加数据库迁移或更改业务表结构;没有自动合并旧用户数据,也没有修改账号版 AuthManager 的凭据刷新逻辑。
  • 本机账号版定点补丁经过正常退出和两次启动,已有数据的内容摘要保持一致;这不是完整公开发行包、Windows 整机重启或断电验证。Linux/macOS 尚未实跑。
  • 本 PR 提供风险修复与可复现的回归覆盖,不保证在所有外部写入、磁盘或电源故障场景下不会丢数据;#4339 的事故起因仍需独立调查。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant