跳转至

Project 三渠道备份策略

版本:v1.0

日期:2026-08-30

状态:首轮基线、本机快照和 Cloudreve 单向控制器已实施;DD 每日单向副本在完成独立恢复验收后启用。

1. 权威源与目标

101 /root/project 是唯一源目录和代码权威。三条渠道均为单向接收,不得反向覆盖 101。

渠道 目标 保留策略 频率
101 /srv/codex-hub-backup 本机灾难恢复与回滚 3 份每日、2 份每周、3 份每月;重大变更前快照保留 7 天 每日 + 变更前触发
Cloudreve Project WebDAV 跨设备取得当前项目状态 只保留当前镜像,不额外维护历史版本 每 5 分钟轮询变化
DD /root/project 异地主机恢复 1 份当前完整副本 + 2 份历史副本 首次压缩基线;之后每日一次,重大变更后可自动触发

2. 实现选型

方案 可维护性 部署复杂度 性能 学习成本 决策
WebDAV 直接挂载作为工作区 低;缓存、锁和 Unix 语义不稳定 低 受缓存和网络影响 低 禁止用于活动工作区
rclone 单向同步/复制 高;支持过滤、清单、重试和 dry-run 中 适合周期性扫描 低 Cloudreve 候选,先完成行为烟测
rsync/SSH 直接复制到 DD 中;目录语义好但数据面受 SSH 路由约束 中 高 低 不经 Tailnet 传输前不得启用
自研实时同步守护进程 低;需自行处理冲突、锁、删除和恢复 高 未知 高 不采用

Cloudreve 使用单向轮询镜像,不宣称事件级实时。Cloudreve 首次基线采用单个压缩包上传,解压后得到与 101 对应的目录树;后续轮询只更新变化内容。DD 首次基线采用压缩包经已确认的公网/物理 SSH 入口传输到 DD 临时目录,在 DD 端解压、清单校验后写入 /root/project;后续每日任务使用保留目录结构的增量副本。Tailnet 只用于控制,不作为文件传输通道。

3. 删除与异常处理

  • 101 源目录允许正常新增、修改和删除。
  • Cloudreve 对应删除使用其原生回收站;不另建第二套 Cloudreve 回收机制。
  • Cloudreve 覆盖是否进入原生回收站必须在实施前用临时对象实测;若不会保留旧对象,按“当前镜像不保留历史版本”处理。
  • DD 的目标异常少文件不得自动确认删除;通过清单校验后从 101 修复,明确源端删除后才传播删除。
  • 单个目标失败只暂停该目标并退避重试,不停止 101 工作区或其他目标。
  • 同一目标禁止并发运行多个同步任务。

4. 本机快照与空间保护

本机快照按以下层级保留:

  • 每日:最近 3 份;
  • 每周:最近 2 份;
  • 每月:最近 3 份;
  • 重大变更前:临时快照保留 7 天。

备份盘 /srv/codex-hub-backup 必须确认来源为 /dev/sda1。空间阈值:

  • 目标:至少保留 220G 可用空间;
  • 警告:可用空间低于 250G;
  • 暂停新快照或新同步写入:低于 220G;
  • 紧急保护:低于 200G,仅允许恢复和清理过期回收对象。

空间不足时不得静默改写 /backup 或系统盘。

5. 实施前验收门

  1. 使用 101 Project 凭据完成 Cloudreve 临时目录读取、上传、下载、SHA-256 回读和删除烟测。
  2. 实测 Cloudreve 覆盖行为与原生回收站行为。
  3. 对 AgentMeshOS 执行 Cloudreve 5 分钟轮询 dry-run,只生成差异清单,不执行删除。
  4. 验证 DD 的 /root/project 目录结构、权限边界和非 Tailnet 数据传输路径。
  5. 验证清单、哈希、失败退避、单目标锁和空间阈值。
  6. 完成 AgentMeshOS 的 Cloudreve 压缩包解压与校验。
  7. 完成 AgentMeshOS 的 DD 压缩基线传输、解压、清单校验和恢复演练。
  8. 两个目标的首轮基线均通过后,才允许按同一压缩基线方式扩展到全部 /root/project。

全量基线与后续增量边界

  • 全量基线允许采用压缩包,以减少大量小文件的请求/往返开销。
  • 压缩包必须在目标端临时目录中接收,完成 SHA-256、文件数量和总大小校验后才解压到目标目录。
  • 解压失败不得覆盖目标现有副本;临时包和失败 staging 目录必须保留必要证据后清理。
  • 全量基线完成后,Cloudreve 继续每 5 分钟更新当前镜像;DD 继续每日增量副本并保留 2 个历史副本,不重复上传完整压缩包。

Cloudreve 写入故障记录(2026-08-30)

首次 PUT/DELETE 烟测返回 500,但根目录 PROPFIND 和文件 GET 正常。现场核对 DD Cloudreve 容器后确认:默认存储策略原指向容器数据库卷 /cloudreve/data/uploads/{uid}/{path},实际业务上传目录挂载在 /cloudreve/uploads,因此所有写入操作均失败。已先备份 cloudreve.db,再将策略修正为 /cloudreve/uploads/{uid}/{path} 并重启 Cloudreve。修复后临时文件 PUT 返回 201、GET 返回 200 且内容一致、DELETE 返回 204;AgentMeshOS dry-run 通过。后续验收固定分离检查 PROPFIND、PUT、GET/哈希回读和 DELETE 四项,不再以单一 HTTP 可达性判断写入健康。

当前结论:Cloudreve 写入链路已通过最小烟测;同步服务、Cloudreve 写入和 DD 副本仍未启用。

后续实施现场记录(2026-08-30)

  • 101 现场身份为 pcdell-101;/srv/codex-hub-backup 当前挂载源为 /dev/sda1,可用空间约 309G;101 角色备份和 Nomad 备份 timer 保持启用,Project 两个远端 timer 保持禁用。
  • 已生成本机第一份每日快照 project-snapshots/daily/20260830T163731Z.tar.gz,绑定清单、文件数、总字节数和 SHA-256 均已回读校验;隔离恢复抽查从快照恢复 AgentMeshOS,清单文件可读,抽样脚本哈希可计算。
  • 已新增 project-baseline-register.sh,将三方路径、计数、字节数、清单摘要、抽样哈希和初始压缩包校验值写入独立备份盘。Cloudreve 完整递归列举现场超过 120 秒未返回,脚本标记 unavailable 并保留失败目录,不把不可读状态记为成功;这属于待解决的 Cloudreve 列举性能/接口问题,不影响 101 快照或 DD 控制器。
  • 已新增 project-local-snapshot.sh 及对应 systemd 模板,强制 /dev/sda1、空间阈值和分层保留;Cloudreve/DD 控制器已加入同一可用空间闸门。两个远端 unit 明确以 copy 模式部署,但 timer 尚未启用。
  • Cloudreve 采用流式 rclone lsf --format ps 后可持续读取对象;完整清单在当前公网 WebDAV 对象量下仍可能超过受控窗口,因此基线记录会明确标为 unavailable,不得把部分清单当作完整一致性证明。已对关键文件执行 Cloudreve 下载恢复抽查,AGENTS.md 哈希一致;控制脚本已完成一次受控增量更新并回读哈希一致。
  • DD 实际增量副本已通过公网 192.227.170.39:17106,无删除项;新增 /var/lib/agentmeshos/project-dd-history,每次实际副本前以硬链接保存历史点并自动最多保留 2 份。DD 本地隔离恢复演练通过,AgentMeshOS/AGENTS.md 哈希与源一致,共恢复 47,285 个文件;目标不存在 /root/project/project。
  • 备份保护演练通过:设置虚拟低空间阈值时任务拒绝写入;并发启动第二个 DD 任务时返回 status=skipped reason=lock。因此异常目标不会阻塞 101 或另一个目标。
  • Cloudreve 故障恢复演练通过:将单次运行窗口压缩为 1 秒后任务记录 status=fail reason=timeout_or_rclone_error 并退出,未留下悬挂同步进程;随后对关键控制文件执行上传、下载和 SHA-256 回读,哈希一致。控制器使用 TERM 后 5 秒强制 KILL,防止 WebDAV 长请求积压。
  • Cloudreve 已改为“根文件 + 顶层目录并行”扫描;完整 /root/project dry-run 连续 3 个周期通过,每周期约 2 分钟,目标固定为 project:。随后执行一次真实增量镜像,三个关键文件上传、下载和 SHA-256 回读一致。
  • Cloudreve 与 DD 的恢复演练、失败重试、DD 中断/锁、空间阈值、历史隔离和目录层级验收均已完成;满足启用远端 timer 的前置门槛。
  • 17:55-17:58 首轮远端 timer 实际运行:Cloudreve copy 成功(约 2 分 22 秒),DD copy 成功(约 36 秒);两个 timer 均保持 enabled/active,101 本机快照 timer 继续运行。
  • Cloudreve 删除语义已补齐:控制器改用受控 rclone sync,先完成全量 dry-run(约 4 分 25 秒),再完成真实 sync(约 4 分 41 秒);删除烟测文件经 WebDAV DELETE 后再次读取返回 directory not found,未建立第二套回收系统。源端排除目录不会被误删,目标仍固定为 project:。

DD 首次压缩基线验收(2026-08-30)

已将完整 project-full-20260830.tar.gz 经公网 SSH 入口传输到 DD /var/lib/agentmeshos/project-dd-baseline/,远端 SHA-256 与 101 本地值一致。DD 端使用 --strip-components=1 解压到 staging,再将原 /root/project 保留至 current-before-baseline 后原子切换;新目标顶层目录和约 9.4G 容量与 101 一致,抽样文件哈希通过。压缩包生成后 101 的 Cloudreve 控制器又发生路径修正,因此个别新文件哈希与该历史基线不同,后续增量副本需补齐;DD 定时器仍保持禁用。

Issue #36 边界修正(2026-08-31)

本页前述 Cloudreve/DD 远端 timer、rclone sync、递归远端清单和“满足启用门槛”的现场记录均为历史方案,不是现行声明。101 已归档并退役 agentmeshos-project-baseline.service/.timer 及其递归 Cloudreve 清单脚本,原因是该路径会产生不受新控制器限额约束的 WebDAV 递归列举。现行状态如下:

  • 101 /root/project 是唯一写入源,Cloudreve 仅由唯一受限单向控制器写入;该控制器不得使用远端递归列举、rclone sync、bisync 或挂载。
  • Cloudreve Project timer 已恢复为唯一受限单向控制器,删除以本地清单为准并保留审计与独立盘恢复材料;不得恢复递归远端清单、rclone sync、bisync 或挂载。
  • DD 副本是独立的每日单向恢复链路:101 通过已登记的公网/物理 SSH 入口向 DD /root/project 增量复制,DD 在复制前保留当前副本的隔离历史,最多保留 2 份。DD 不持有 Project WebDAV 凭据,不能向 101 回写,也不经 Tailnet 传输。
  • DD timer 的启用前置是目标身份、SSH host key、独立盘快照、rsync --dry-run、实际增量、删除隔离、清单/哈希回读和重启恢复均通过。任一项失败时停止 DD timer,保留 101 源和 DD 历史副本后再排障。