cr4sync mgr(alias migrate)
第三方网盘 → Cloudreve 单向迁移。支持 baidu / onedrive / aliyun / pikpak / webdav / cloudreve / s3 / oss / cos。真流式(不落盘) + 断点续传 + 端到端一致性校验。
用法
cr4sync mgr -s main-baidu # 跑 [[storage]] 中 name=main-baidu 的实例
cr4sync mgr -s main-baidu /我的资源/sub # 临时覆盖 source_path (只迁子目录)
cr4sync mgr -s main-baidu /a.zip cloudreve://my/a.zip # 单文件
cr4sync mgr -s main-baidu --rate-limit 8 --parallelism 8
cr4sync mgr -s main-baidu --force-rewrite # 把本次扫描命中的任务踩回 pending 重传
cr4sync mgr -s main-baidu --force-reset -y # 清空整个 migrate.db (危险, -y 跳过确认)
参数
| 参数 | 类型 | 默认 | 说明 |
|---|---|---|---|
[source_path] | string | [[storage]].root_path | 源端路径或 URI(如 baidu:///我的资源),覆盖 storage 配置。 |
[target_path] | string | [[storage]].target_path | 目标 Cloudreve URI(如 cloudreve://my/backup)。 |
-s, --source <NAME> | string | 仅一个 baidu storage 时可省 | 选 [[storage]] 实例。 |
--parallelism <N> | u32 | 派生自 rate_limit,上限 8 | 并发数。 |
--rate-limit <QPS> | u32 | [[storage]].rate_limit 或 3 | 源端 API QPS 上限。 |
-y, --yes | flag | false | 跳过预览/确认提示。 |
--force-rewrite | flag | false | 把本次 scan 命中的任务(含 completed)踩回 pending 重传。只动本次涉及行。 |
--force-reset | flag | false | 清空整个 migrate.db。带 y/N 确认(-y 跳过)。与 --force-rewrite 互斥。 |
工作原理
ensure_session → for idx in next_chunk..N {
baidu download_range(offset, len)
→ progress bar inc
→ cloudreve upload_chunk(idx, &bytes)
→ db.update_next_chunk(idx+1)
}
→ [若远程存储策略] complete_upload
→ mark_verifying
→ verify_consistency (size + 头尾 8KB blake3)
→ mark_completed
- 不落盘:每片下载完立即喂上传,drop bytes。内存峰值 =
chunk_size × parallelism,单文件 3T 也能跑。 - 断点续传:进度持久化到
./credential/migrate.db,每片上传后写next_chunk。Ctrl-C 或崩溃重跑从那一片接。 - 一致性校验:cloudreve
/file/info不返 md5,只能 size + 头/尾 8KB blake3 兜底;< 16KB 文件仅信任 size。
状态机
pending ──► uploading ──┬─► verifying ──► completed
│
▼
failed (next run: 复用 next_chunk 续传)
verify_failed (next run: 清空 session + next_chunk=0 重头)
migrate_task 表的 state 字段记录每个任务的当前状态。
进度展示
indicatif::MultiProgress 槽位 bar 池:
[####################------] 3.2 MiB/4.0 MiB ( 1.2 MiB/s, ETA 1s) 上传 chunk 8/16 /我的资源/a.mp4
[######------------------- ] 200.0 KiB/4.0 MiB ( 800 KiB/s, ETA 5s) 下载 chunk 2/16 /我的资源/b.zip
[##########################] 完成 (空闲)
bar 数量 = parallelism,与文件数解耦。空闲槽位 idle_slot_bar 状态等待领取下一文件。
--force-rewrite vs --force-reset
| 操作 | 影响行 | completed 行 | 其他 storage 行 |
|---|---|---|---|
--force-rewrite | 仅本次扫描命中的行 | 一并踩回 pending | 不动 |
--force-reset | 全表 | 一并删除 | 一并删除 |
远端文件被外部删了想重传 → --force-rewrite。
migrate.db 损坏想从零 → --force-reset。
鉴权失败处理
百度 refresh_token 也过期 → CliError::Auth → run_concurrent 立即 JoinSet::shutdown,提示 cr4sync login --baidu。
已知限制
- driver:接受
"baidu"/"onedrive"/"aliyun"/"pikpak"/"webdav"/"cloudreve"/"s3"/"oss"/"cos"。 - 校验粒度:cloudreve v4 不返 md5,中段被篡改理论可漏判。
- dlink 8h 时效:百度单文件 chunk 循环超 8h 由
get_dlink自然续期,调用方无感。 - 校验失败需手动:标记
verify_failed的任务下次跑会清 session 重头传一次;再失败需--force-rewrite或排查源/目标差异。