[D-04][medium] 备份与恢复不安全:库不存在时静默新建空库并报成功,恢复步骤没要求清理 -wal/-shm #30

Closed
opened 2026-09-30 13:56:57 +08:00 by nixevol · 1 comment
Owner

编号:D-04 严重级:medium 工作线:存储、配置、命令行与部署(internal/store、internal/config、cmd/nixmsg 命令、deploy) 来源:审查 P-18、P-19
依赖:无 被依赖:无

结论与统一方案

采用审查 P-18、P-19 的方案:

  1. 备份前检查 <data_dir>/nixmsg.db 是否存在,不存在就报错并打印解析后的绝对路径;不再创建数据目录;成功时打印源库的绝对路径;输出文件用 0600 权限(备份里有尚未送达的正文)。
  2. OPS 示例里的 data_dir 写成绝对路径(cron 的工作目录通常是家目录,相对路径会指到错误位置)。
  3. 恢复步骤改为:停服务 → 把 nixmsg.db、nixmsg.db-wal、nixmsg.db-shm 三个文件一起移走 → 把备份复制成 nixmsg.db → 启动。可选新增 nixmsg restore --from <文件>,确认服务没在运行后执行上述步骤。

改动文件

cmd/nixmsg/backup.go、docs/OPS.md(可选 cmd/nixmsg/restore.go)。

与其他问题的交互 / 冲突说明

无。

验收与测试

  • 空目录执行备份返回错误,且不会生成 nixmsg.db。
  • 若做 restore 命令:构造残留的 WAL,恢复后 PRAGMA integrity_check 为 ok。

问题明细(各区审查原文,证据含文件与行号)

以下是本次复审各区审查报告的原文段落。A、M、I、P、S 开头的是原始发现编号(A 管理后台与网页、M 消息核心、I 身份认证群在线、P 传输平台部署、S SDK)。解决方案以本 issue 上方的"结论与统一方案"为准;原文里的方案与之不一致时,按上方执行。

[P-18] backup 在库文件不存在时,静默新建空库并报告成功

  • 严重级:medium
  • 分类:数据
  • 现象与影响:
    • store.OpenWriter 会先建数据目录,再以可创建的方式打开 nixmsg.db。
    • 示例配置里 data_dir: "./data" 是相对路径。按 OPS 第 3 节用 cron 执行备份时,工作目录通常是家目录,于是:
      • 在错误的位置新建一个空库;
      • 把这个空库导出去,并打印 "backup written to"。
    • 结果是定时备份一直"成功",到恢复时才发现是空的。
    • 备份文件用默认权限创建(通常是 0644),而里面含有还没送完的正文。
  • 证据:backup.go:31-40;store/db.go:73-92;deploy/config.example.yaml:8。
  • 文档依据:PRD F22「备份文件能在另一目录启动并看到原来的端」、F18(备份含正文,要按敏感数据保管)。
  • 为何不是故意设计:没有记录。
  • 解决方案:
    • 备份前先检查 <data_dir>/nixmsg.db 是否存在,不存在就报错,并打印解析后的绝对路径;
    • 不再创建数据目录;
    • 成功时打印源库的绝对路径;
    • 输出文件改为 0600 权限;
    • OPS 示例里的 data_dir 写成绝对路径。
  • 改动文件:cmd/nixmsg/backup.go、docs/OPS.md
  • 与其他模块的交互/冲突风险:无。
  • 需补测试:空目录执行备份返回错误,且不会生成 nixmsg.db。
  • 置信度:代码阅读确定

[P-19] OPS 的恢复步骤只替换 nixmsg.db,没要求清理 -wal/-shm

  • 严重级:medium
  • 分类:文档 / 数据
  • 现象与影响:
    • OPS 第 3 节的恢复步骤是"停服务,用备份替换 data/nixmsg.db"。
    • 如果旧的 nixmsg.db-wal 还在(非正常退出时一定在,而 P-6 的停机挂起最终靠 SIGKILL 结束),SQLite 打开时只校验 WAL 文件自身,不校验它是否属于这个库文件。
    • 结果是旧库的页会叠加到恢复出来的库上,得到损坏或新旧混杂的数据。
  • 证据:docs/OPS.md 第 3 节"恢复"一段;store/db.go:120-124(WAL 模式)。
  • 文档依据:PRD F22。
  • 为何不是故意设计:文档遗漏。
  • 解决方案:恢复步骤改为:停服务 → 把 nixmsg.db、nixmsg.db-wal、nixmsg.db-shm 三个文件一起移走 → 把备份文件复制成 nixmsg.db → 启动。可选:增加 nixmsg restore --from <文件> 命令,确认服务没在运行后执行上述步骤。
  • 改动文件:docs/OPS.md(可选新增 cmd/nixmsg/restore.go)
  • 与其他模块的交互/冲突风险:无。
  • 需补测试:如果做 restore 命令,构造一个残留的 WAL,恢复后执行 PRAGMA integrity_check 结果为 ok。
  • 置信度:较高(依据 SQLite 的 WAL 机制,未复现)

复审基线:main 4059a15(2026-09-30)。编号说明、各工作线的合并顺序、共享文件归属见总览 #7。

**编号**:D-04 **严重级**:medium **工作线**:存储、配置、命令行与部署(internal/store、internal/config、cmd/nixmsg 命令、deploy) **来源**:审查 P-18、P-19 **依赖**:无 **被依赖**:无 ### 结论与统一方案 采用审查 P-18、P-19 的方案: 1. 备份前检查 `<data_dir>/nixmsg.db` 是否存在,不存在就报错并打印解析后的绝对路径;不再创建数据目录;成功时打印源库的绝对路径;输出文件用 0600 权限(备份里有尚未送达的正文)。 2. OPS 示例里的 `data_dir` 写成绝对路径(cron 的工作目录通常是家目录,相对路径会指到错误位置)。 3. 恢复步骤改为:停服务 → 把 `nixmsg.db`、`nixmsg.db-wal`、`nixmsg.db-shm` 三个文件一起移走 → 把备份复制成 `nixmsg.db` → 启动。可选新增 `nixmsg restore --from <文件>`,确认服务没在运行后执行上述步骤。 ### 改动文件 `cmd/nixmsg/backup.go`、`docs/OPS.md`(可选 `cmd/nixmsg/restore.go`)。 ### 与其他问题的交互 / 冲突说明 无。 ### 验收与测试 - 空目录执行备份返回错误,且不会生成 `nixmsg.db`。 - 若做 restore 命令:构造残留的 WAL,恢复后 `PRAGMA integrity_check` 为 ok。 --- ### 问题明细(各区审查原文,证据含文件与行号) > 以下是本次复审各区审查报告的原文段落。A、M、I、P、S 开头的是原始发现编号(A 管理后台与网页、M 消息核心、I 身份认证群在线、P 传输平台部署、S SDK)。**解决方案以本 issue 上方的"结论与统一方案"为准**;原文里的方案与之不一致时,按上方执行。 #### [P-18] backup 在库文件不存在时,静默新建空库并报告成功 - **严重级**:medium - **分类**:数据 - **现象与影响**: - `store.OpenWriter` 会先建数据目录,再以可创建的方式打开 `nixmsg.db`。 - 示例配置里 `data_dir: "./data"` 是相对路径。按 OPS 第 3 节用 cron 执行备份时,工作目录通常是家目录,于是: - 在错误的位置新建一个空库; - 把这个空库导出去,并打印 "backup written to"。 - 结果是定时备份一直"成功",到恢复时才发现是空的。 - 备份文件用默认权限创建(通常是 0644),而里面含有还没送完的正文。 - **证据**:`backup.go:31-40`;`store/db.go:73-92`;`deploy/config.example.yaml:8`。 - **文档依据**:PRD F22「备份文件能在另一目录启动并看到原来的端」、F18(备份含正文,要按敏感数据保管)。 - **为何不是故意设计**:没有记录。 - **解决方案**: - 备份前先检查 `<data_dir>/nixmsg.db` 是否存在,不存在就报错,并打印解析后的绝对路径; - 不再创建数据目录; - 成功时打印源库的绝对路径; - 输出文件改为 0600 权限; - OPS 示例里的 data_dir 写成绝对路径。 - **改动文件**:`cmd/nixmsg/backup.go`、`docs/OPS.md` - **与其他模块的交互/冲突风险**:无。 - **需补测试**:空目录执行备份返回错误,且不会生成 `nixmsg.db`。 - **置信度**:代码阅读确定 #### [P-19] OPS 的恢复步骤只替换 nixmsg.db,没要求清理 -wal/-shm - **严重级**:medium - **分类**:文档 / 数据 - **现象与影响**: - OPS 第 3 节的恢复步骤是"停服务,用备份替换 data/nixmsg.db"。 - 如果旧的 `nixmsg.db-wal` 还在(非正常退出时一定在,而 P-6 的停机挂起最终靠 SIGKILL 结束),SQLite 打开时只校验 WAL 文件自身,不校验它是否属于这个库文件。 - 结果是旧库的页会叠加到恢复出来的库上,得到损坏或新旧混杂的数据。 - **证据**:`docs/OPS.md` 第 3 节"恢复"一段;`store/db.go:120-124`(WAL 模式)。 - **文档依据**:PRD F22。 - **为何不是故意设计**:文档遗漏。 - **解决方案**:恢复步骤改为:停服务 → 把 `nixmsg.db`、`nixmsg.db-wal`、`nixmsg.db-shm` 三个文件一起移走 → 把备份文件复制成 `nixmsg.db` → 启动。可选:增加 `nixmsg restore --from <文件>` 命令,确认服务没在运行后执行上述步骤。 - **改动文件**:`docs/OPS.md`(可选新增 `cmd/nixmsg/restore.go`) - **与其他模块的交互/冲突风险**:无。 - **需补测试**:如果做 restore 命令,构造一个残留的 WAL,恢复后执行 `PRAGMA integrity_check` 结果为 ok。 - **置信度**:较高(依据 SQLite 的 WAL 机制,未复现) --- <sub>复审基线:main `4059a15`(2026-09-30)。编号说明、各工作线的合并顺序、共享文件归属见总览 #7。</sub>
nixevol added the P2-mediumlane/storereview-2026-09-30 labels 2026-09-30 13:56:57 +08:00
Author
Owner

已合入 origin/main 0c9b459。落地提交 57c2f70 fix: 修复写队列 busy 恢复、关闭安全、备份与配置构建问题 (#30)。

已合入 origin/main `0c9b459`。落地提交 `57c2f70` fix: 修复写队列 busy 恢复、关闭安全、备份与配置构建问题 (#30)。
Sign in to join this conversation.