Backup-Real-Matters 是一个面向“真正重要文件”的轻量备份系统:
- 只关注有修改历史的文件(文件的修改时间不等于创建时间,意味着这个文件被修改过,包含你的创造性劳动;反之如果文件创建后无任何修改,说明这个文件很可能是不重要的文件,可随时从互联网上重新下载)
- 只关注文档等小文件(可配置单个备份最大文件大小)
- 支持读取每个目录下存在的
.gitignore,自动忽略无备份价值的构建文件等 - 通过 内容寻址存储 自动去重,降低重复上传和存储的文件
- 提供CLI工具,支持 按快照浏览 和 按文件恢复
适合:文档、代码、脚本、配置等高价值小文件的持续备份。
不适合:大体积媒体文件、整盘镜像备份。
很多备份工具“全量思维”太重:数据量大、耗时长、成本高。
本项目聚焦一个更实用的目标:
- 只备份你最关心、最常变更、体积较小的文件
- 尽量减少重复数据上传
- 能快速回到某个历史版本
- 小文件优先:支持
max_file_size_bytes,默认1048576(1 MiB) - 内容去重:文件按 SHA-256 哈希去重,远端只保留一份对象
- 快照索引:SQLite + SeaORM 记录“某次快照中某路径对应哪个对象”
- 远端存储:将缺失对象打成单个
tar.gz后一次上传到远端objects/目录 - 索引异地副本:每次
run/gc后将本地index.db压缩上传到远端db/index.db - GC 清理:按“每路径保留版本数 + 陈旧策略”自动清理历史映射与孤儿对象
- 文件恢复:支持“最新版本恢复”或“指定快照恢复”
backup-real-matters-core:核心引擎(配置、扫描、哈希、数据库、远端同步、GC、恢复)backup-real-matters-cli:命令行入口(定时任务、运维脚本友好)
数据流(简化):
- 扫描目录(按 ignore 规则 + 文件大小上限)
- 对候选文件计算 SHA-256
- 将缺失对象打成单个
tar.gz上传到远端后再解包落盘 - 写入快照映射到本地 SQLite
- 可选执行 GC
- 将最新
index.db备份到远端db/(仅做灾备副本)
- Rust(建议 stable)
- 可用的
ssh/scp客户端 - 本机需有
tar(用于生成批量上传tar.gz) - 远端主机需有
tar(用于解包批量上传的tar.gz) - 一台可 SSH 访问的远端主机(或本机 SSH)
先安装命令行工具,后续可直接使用 backup-real-matters-cli 命令:
cargo install --git git@github.com:MrAMS/Backup-Real-Matters-v2.git backup-real-matters-cli如果你已经在本地 clone 了仓库,也可以直接从本地源码安装:
cargo install --path backup-real-matters-cli更新到最新版本时可加 --force 重新安装。
backup-real-matters-cli init默认生成目录:~/.config/backup-real-matters
$EDITOR ~/.config/backup-real-matters/dirs.conf
$EDITOR ~/.config/backup-real-matters/server.conf
$EDITOR ~/.config/backup-real-matters/ignores.confbackup-real-matters-cli run运行时会输出相对上一快照的 added/deleted/modified 文件清单。
如需先看“相对最新快照会新增/删除/修改哪些文件”:
backup-real-matters-cli run --drybackup-real-matters-cli snapshots --limit 20
backup-real-matters-cli files 1# 恢复最近一次版本
backup-real-matters-cli restore /abs/path/to/file
# 恢复指定快照版本
backup-real-matters-cli restore /abs/path/to/file --snapshot-id 12
# 恢复到新位置
backup-real-matters-cli restore /abs/path/to/file --output /tmp/recovered.txt --overwrite默认配置目录:~/.config/backup-real-matters
每行一个要扫描的根目录(建议写绝对路径):
/home/your_name/Documents.gitignore 风格规则,例如:
node_modules/
target/
.git/
*.tmp
*.log同时,扫描时会自动读取各目录中的 .gitignore 并应用其忽略规则(即使该目录不是 Git 仓库)。
target=user@example.com
remote_root=.backup-recent
index_db=~/.config/backup-real-matters/index.db
keep_recent_versions=5
stale_days=7
deleted_retention_days=0
max_file_size_bytes=1048576
mtime_created_equal_threshold_secs=3参数说明:
target:SSH 目标(必填)remote_root:远端根目录(相对路径会解析到远端~/...)index_db:本地 SQLite 路径- 正常运行/恢复始终使用本机
index_db - 远端
db/index.db仅用于“本机磁盘损坏时”的灾备兜底
- 正常运行/恢复始终使用本机
keep_recent_versions:每个文件路径保留最近 N 个版本stale_days:若最新版本已陈旧,收缩为仅保留 1 个版本deleted_retention_days:文件被删除后,超过 N 天将其全部历史版本从备份中彻底清零(0表示禁用该策略)max_file_size_bytes:单文件大小上限(本项目默认只备份小文件)mtime_created_equal_threshold_secs:当|mtime-创建时间| <= N秒时视为“几乎相同”(默认3,不回退到ctime)
init [--force]:初始化配置模板run [--no-gc] [--notify]:执行一次备份,并输出相对上一快照的新增/删除/修改文件列表run过程中会输出 hashing / upload 进度(stderr)run --dry:仅预览“相对最新快照”的新增/删除/修改文件列表(不上传、不写快照、不执行 GC)gc:只执行 GCsnapshots [--limit N]:列出快照(含added/deleted/modified)diff <snapshot_a> <snapshot_b>:输出两个快照(A -> B)的新增/删除/修改文件明细files <snapshot_id>:列出快照内文件versions <file_path> [--limit N]:列出该文件的不同内容版本(按快照时间倒序)restore <file_path> [--snapshot-id ID] [--output PATH] [--overwrite]:恢复文件install-systemd [--daily-at HH:MM] [--notify]:安装 systemd user 每日定时任务模板uninstall-systemd:卸载 systemd user service/timer 模板
安装“每天固定时刻运行一次”定时任务(示例:每天 03:30):
backup-real-matters-cli install-systemd --daily-at 03:30 --notify
systemctl --user daemon-reload
systemctl --user enable --now backup-real-matters.timer说明:
- 使用
OnCalendar=*-*-* HH:MM:00按本地时间每天触发一次 Persistent=true已开启:如果关机错过了触发,开机后会补跑一次(只补一次)
卸载:
backup-real-matters-cli uninstall-systemd
systemctl --user daemon-reload- 恢复默认不覆盖已存在文件,需显式
--overwrite - 远端对象上传为“本地暂存 ->
tar.gz单文件上传 -> 远端解包 + 原子落盘”,减少小文件逐个 SSH 往返 - GC 只删除“无引用对象”
- 项目定位是“小文件重要版本备份”,非整机镜像工具
cargo fmt --all
cargo clippy --workspace --all-targets -- -D warnings
cargo test --workspace- 完整测试方案:
TEST_PLAN.md - SSH 端到端自动化脚本(隔离到
/tmp):e2e_watchman.sh - watchman 实机全流程手册:
docs/WATCHMAN_FULL_FLOW_TEST.md
远端 SSH 服务未启动或端口不可达,请先确认远端 SSH 可用。
恢复默认不覆盖,请追加 --overwrite。
重点检查三项:
- 是否命中
ignores.conf - 是否超过
max_file_size_bytes - 是否在扫描规则中过滤(如时间戳条件)
backup-real-matters-core/:核心库backup-real-matters-cli/:CLIbackup-real-matters-cli/systemd/:systemd 模板examples/config/:示例配置TEST_PLAN.md:完整测试方案
已完成:
- 核心数据库与实体(
objects/snapshots/snapshot_files) - 扫描 + SHA-256 流式哈希 + CAS 去重上传
- 快照写入、GC 清理、恢复链路(core/cli)
- 单元测试 + 端到端 SSH 自动化脚本
待增强(后续迭代):
- 多线程哈希/上传调度优化
- 更完善的远端异常重试策略