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. 实施前验收门
- 使用 101 Project 凭据完成 Cloudreve 临时目录读取、上传、下载、SHA-256 回读和删除烟测。
- 实测 Cloudreve 覆盖行为与原生回收站行为。
- 对
AgentMeshOS执行 Cloudreve 5 分钟轮询 dry-run,只生成差异清单,不执行删除。 - 验证 DD 的
/root/project目录结构、权限边界和非 Tailnet 数据传输路径。 - 验证清单、哈希、失败退避、单目标锁和空间阈值。
- 完成
AgentMeshOS的 Cloudreve 压缩包解压与校验。 - 完成
AgentMeshOS的 DD 压缩基线传输、解压、清单校验和恢复演练。 - 两个目标的首轮基线均通过后,才允许按同一压缩基线方式扩展到全部
/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/projectdry-run 连续 3 个周期通过,每周期约 2 分钟,目标固定为project:。随后执行一次真实增量镜像,三个关键文件上传、下载和 SHA-256 回读一致。 - Cloudreve 与 DD 的恢复演练、失败重试、DD 中断/锁、空间阈值、历史隔离和目录层级验收均已完成;满足启用远端 timer 的前置门槛。
- 17:55-17:58 首轮远端 timer 实际运行:Cloudreve
copy成功(约 2 分 22 秒),DDcopy成功(约 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 历史副本后再排障。