rsnapshot 适合在 Linux 备份服务器上保存“能直接浏览的历史版本”。它以 rsync 完成同步,并通过硬链接复用未变化的文件。
因此,daily.0、daily.1、weekly.0 看起来都像完整备份,但相同文件通常只占一份数据空间。恢复时也不需要导入专用数据库,找到对应快照并复制文件即可。
本文按四类来源展开:
- Linux 本机目录;
- 通过 SSH 访问的远程 Linux 目录;
- Windows 或 Samba 共享;
- 通过 SMB/CIFS 或 NFS 提供文件的 NAS。
示例统一把快照写入:
|
|
正式操作前,请把示例 IP、用户名、共享名和目录替换成自己的值。
功能介绍与基本命令
rsnapshot 的数据流
最常见的部署方式是让一台 Linux 机器充当备份服务器:
|
|
备份服务器负责读取源数据、写入快照、执行定时任务和保存日志。对于远程 Linux,rsnapshot 通过 SSH 主动拉取;对于 Windows 或 NAS,共享目录通常先挂载到 Linux,再按本地目录备份。
rsnapshot 不是实时同步工具,也不是异地备份策略本身。它能降低误删、误改和需要历史版本时的恢复成本,但无法替代离线副本、异地副本和恢复演练。
安装所需软件
Ubuntu 或 Debian 可以安装:
|
|
各组件用途如下:
rsnapshot:管理同步和快照轮转;rsync:复制变化的数据;openssh-client:连接远程 Linux;cifs-utils:挂载 Windows、Samba 和常见 NAS 的 SMB 共享;nfs-common:挂载 NAS 的 NFS 导出。
确认命令位置:
|
|
本文示例使用 /usr/bin/rsnapshot、/usr/bin/rsync 和 /usr/bin/ssh。如果系统输出不同,应以实际路径为准。
先检查备份盘
创建快照根目录:
|
|
快照根目录应位于支持硬链接的 Linux 文件系统上,例如 ext4 或 XFS。不要把它直接放到 FAT、exFAT 等不支持 Unix 硬链接的文件系统中。
如果 /mnt/backup 是独立硬盘,还要确认它确实已经挂载。否则磁盘挂载失败后,任务可能把备份写进系统盘上的同名空目录。
可先做一次硬链接测试:
|
|
两个测试文件的 inode 号应相同。
配置文件的基本结构
主配置通常是 /etc/rsnapshot.conf:
|
|
配置项和参数之间必须使用 Tab 制表符。代码块显示宽度可能与编辑器不同,粘贴后应检查实际字符,不能用一串普通空格代替 Tab。
这组保留策略表示:
- 保存 7 个每日快照;
- 保存 4 个每周快照;
- 保存 6 个每月快照。
默认模式下,列表中最频繁的 daily 执行实际 rsync 同步并轮转每日快照;weekly 和 monthly 主要把较低层级的旧快照向上轮转。若启用了 sync_first 1,行为会改变,不能再照搬本文的定时方式。
常用命令速查
检查配置语法:
|
|
正常结果应包含:
|
|
预览命令但不实际备份:
|
|
执行每日同步:
|
|
查看快照占用:
|
|
使用自定义配置文件:
|
|
如果任务由普通用户 test 运行,则检查、SSH 密钥和目录权限都必须属于同一个用户:
|
|
备份 Linux 目录
备份本机目录
假设备份以下目录:
|
|
在 /etc/rsnapshot.conf 中添加:
|
|
当全局 rsync_long_args 包含 --relative 时,来源的目录层级会保留,结果通常类似:
|
|
先执行:
|
|
仔细检查 dry-run 输出中的源路径和目标路径,确认不会写错位置,再正式执行:
|
|
通过 SSH 备份远程 Linux
假设环境如下:
|
|
远程机器通常不必安装 rsnapshot,但必须运行 SSH 服务,并且远程环境中要有 rsync。
先在远程机器确认:
|
|
如果 rsnapshot 由 root 的 cron 运行,就为 root 配置 SSH 密钥:
|
|
最后一条命令必须能够直接登录,不能要求输入密码或确认 host key。
如果任务由 test 用户运行:
|
|
配置备份点:
|
|
之后依次验证:
|
|
如果使用 --relative,快照中可能保留 data/files 这一层。这不是重复备份,而是 rsync 的相对路径行为。
控制远程目录在快照中的层级
如果希望 /data/files/ 内的内容直接出现在 remote-linux/ 下,可用 /./ 标记相对路径起点:
|
|
备份结果会更接近:
|
|
路径语义容易被末尾斜杠和 --relative 影响,所以不要只凭预期判断。应先运行 rsnapshot -t daily,必要时再直接做一次 rsync dry-run。
非标准 SSH 端口
远程 SSH 端口为 2222 时,可在全局配置中写:
|
|
先手动测试:
|
|
如果只有一台服务器使用特殊端口,建议改用 ~/.ssh/config,避免全局 ssh_args 影响其他备份点:
|
|
对应配置为:
|
|
备份多台 Linux 主机
每个来源使用独立目标名称:
|
|
这样恢复时可以立即看出数据来自哪台机器,也能避免不同来源写入同一目录。
只备份根目录下的 .git 裸仓库
假设 NAS 上的目录为:
|
|
只保留根目录下以 .git 结尾的目录及其全部内容:
|
|
前三处分隔使用 Tab,第四列中的 rsync 参数使用普通空格。+rsync_long_args= 表示追加到全局参数,而不是整体替换。
过滤规则顺序不能颠倒。rsync 按第一条匹配规则决定是否包含对象,所以 --include=/*.git/*** 必须位于 --exclude=* 前面。
先直接测试 rsync:
|
|
输出中应出现 .git 目录及其内容,不应出现 website/、test/ 或 README.txt。
如果规则后来由“备份全部”改成“只备份 .git”,旧快照里的其他内容不会因此从历史快照消失。若要让新的 daily.0 清理已排除对象,需要理解并测试 --delete-excluded 的影响;它可能删除目标中不再匹配过滤规则的数据,不能在未经 dry-run 验证时直接启用。
备份远程 Windows 共享、NAS 和 Samba 目录
选择 SMB、NFS 还是 SSH
可按来源能力选择:
- Windows 文件共享:通常使用 SMB/CIFS;
- Samba 服务器:通常使用 SMB/CIFS,也可以直接通过 SSH + rsync;
- 群晖、威联通等 NAS:可使用 SMB/CIFS、NFS,或在可控环境中使用 SSH + rsync;
- 远程 Windows 已配置 OpenSSH 和 WSL rsync:可以通过 SSH 拉取,但部署和路径处理更复杂。
对于普通 Windows 共享,最容易维护的方式是先在 Linux 上只读挂载,再让 rsnapshot 备份挂载点。
创建 SMB 凭据文件
不要把密码直接写在 /etc/fstab 或命令历史中。创建 root 可读的凭据文件:
|
|
内容为:
|
|
如果不使用域,可删除 domain 行。再确认权限:
|
|
预期权限是 600 root:root。
手动挂载 Windows 或 Samba 共享
假设共享地址为 //192.168.8.100/files:
|
|
验证挂载和读取:
|
|
先确认共享能稳定读取,再写入 rsnapshot 配置。若手动挂载都失败,rsnapshot 不会解决认证、协议或网络问题。
配置开机自动挂载
在 /etc/fstab 中加入一行:
|
|
测试时不要直接重启:
|
|
其中:
ro:以只读方式挂载,降低备份机误改源数据的风险;credentials=:从独立文件读取账号密码;vers=3.0:明确尝试 SMB 3.0;_netdev:标记这是依赖网络的挂载;nofail:挂载失败时不阻止系统继续启动。
nofail 只影响启动行为,不代表备份任务应忽略挂载失败。定时备份前仍然必须检查挂载状态。
把 SMB 挂载点加入 rsnapshot
配置:
|
|
然后验证:
|
|
不要只检查目录是否存在。即使 SMB 挂载已经掉线,本地挂载点目录仍可能存在,但里面是空的。
挂载 NAS 的 NFS 导出
假设 NAS 导出 192.168.8.200:/volume1/files:
|
|
对应 /etc/fstab 示例:
|
|
rsnapshot 配置:
|
|
NFS 的用户映射和权限模型与 SMB 不同。能挂载不等于能读取全部文件,应使用实际运行 rsnapshot 的账户递归抽查目录。
防止共享掉线后生成空快照
最简单的 cron 防护是先检查所有必要挂载点:
|
|
如果任意挂载点不存在,rsnapshot 不会执行。
还可以再检查一个只存在于共享中的哨兵文件:
|
|
哨兵文件能够发现“挂载点存在但挂载的是错误共享”等问题。文件应由源端管理员创建,并保证备份账户可读。
定时备份与快照轮转
推荐的 cron 顺序
假设配置为:
|
|
可编辑 root 的 crontab:
|
|
写入:
|
|
真正写入 crontab 时,星号前不要添加反斜杠。
高级别轮转安排在每日同步之前,是为了让 monthly、weekly 先接收即将从较低层级淘汰的快照。每月 1 日恰好也是星期日时,执行顺序为 monthly、weekly、daily。
给多个层级加同一个锁
磁盘慢、文件多或网络不稳定时,一次 daily 可能运行到 weekly 的计划时间。可用 flock 防止重叠:
|
|
-n 表示拿不到锁就立即退出。这样不会同时启动两个 rsnapshot,但要结合日志监控,避免任务长期因锁冲突而被跳过。
如果 daily 前必须检查 SMB 和 NFS 挂载,建议写一个 root 拥有、不可被普通用户修改的包装脚本,再由 cron 调用。不要在 crontab 里堆叠过长的复合命令。
首次启用定时任务前的验收
依次完成:
|
|
还要确认 cron 使用的 root 能免交互连接每一台远程 Linux:
|
|
命令应直接返回成功,不应等待密码或首次连接确认。
验证硬链接确实生效
连续生成两个快照后,选择一个未变化文件:
|
|
若 inode 相同且硬链接计数大于 1,说明两个快照共享同一份文件数据。
不要用 du -sh daily.0 daily.1 简单相加来估算真实新增空间。硬链接会让逐目录统计看起来像每个快照都占一份完整容量。
恢复文件
恢复前先浏览历史快照:
|
|
将文件恢复到临时目录:
|
|
先检查恢复文件,再决定是否覆盖生产目录。恢复到远程服务器时,建议先 rsync 到临时位置,并由业务负责人确认权限、所有者和内容。
常见问题与错误处理
configtest 报错或提示字段数量不对
最常见原因是 Tab 被替换为空格。显示不可见字符:
|
|
Tab 通常显示为 \t。修正后重新执行:
|
|
还要检查命令路径是否真实存在,以及 snapshot_root 是否可读写。
Permission denied (publickey)
这表示执行任务的本地账户无法通过 SSH 密钥登录。用同一账户测试:
|
|
检查以下项目:
- 公钥是否加入远端账户的
~/.ssh/authorized_keys; - 本地私钥是否属于运行 rsnapshot 的账户;
- 远端
.ssh和authorized_keys权限是否过宽; - cron 是否实际以 root 而不是
test运行; - host key 是否已经由同一账户确认。
SSH 能登录,但 rsync 报 command not found
确认远端路径:
|
|
如果 rsync 位于非标准位置,可为对应备份点追加:
|
|
不要猜路径,先在远程机器实际确认。
远程目录没有读取权限
先以远程备份账户测试:
|
|
再绕过 rsnapshot 直接测试 rsync:
|
|
如果仍然出现 Permission denied,问题在远端账户的目录遍历或文件读取权限,而不是 rsnapshot。可在远端检查:
|
|
优先通过专用只读账户、组权限或 ACL 授权。不要为了省事把整个源目录改成所有人可读写。
SMB 挂载提示 Permission denied
先查看内核日志和挂载错误:
|
|
检查共享名、用户名、域、凭据文件权限以及 NAS 是否允许该账户访问。只有在服务端确实较旧时才尝试其他 vers=,不要把降级到旧协议当成默认解决办法。
rsnapshot 成功,但 Windows 或 NAS 快照是空的
立即检查源挂载:
|
|
如果共享未挂载,应停止后续轮转,先恢复挂载,再执行 daily。不要在空挂载点上连续运行,否则多个新快照都会反映空源状态。
rsnapshot -t 看起来正确,正式执行仍失败
-t 主要展示将执行的命令,不会完整验证传输期间的权限、容量、网络稳定性和所有文件名。应把 dry-run 视为第一道检查,而不是成功保证。
查看日志:
|
|
再复制日志中的 rsync 命令单独运行,以确认是网络、权限、文件名还是磁盘问题。
磁盘空间异常增长
先区分“文件变动多”和“硬链接失效”:
|
|
大量小文件会先耗尽 inode;数据库文件、虚拟机镜像和持续变化的大文件即使只改了一小部分,也可能在新快照中占用新的完整文件空间。
如果快照根目录被迁移到不支持硬链接的文件系统,或不同快照跨文件系统,空间复用也会失效。重新检查:
|
|
cron 没有执行
确认 crontab 内容:
|
|
cron 环境变量比交互式 shell 少,所以任务中应使用绝对命令路径。不要依赖 shell 中临时设置的 PATH、SSH agent 或手工挂载状态。
如果命令手动能执行、cron 不能执行,优先比较两者的运行账户、HOME、SSH 密钥、known_hosts 和挂载可见性。
任务互相重叠或长期不结束
检查进程:
|
|
不要在不知道进程阶段时直接删除锁文件。先看日志和进程状态,确认没有活跃 rsnapshot 后,再处理遗留锁。
如果经常跨越计划窗口,应调整执行时间、减少扫描范围、修复慢网络,或使用统一的 flock 锁,而不是允许多个任务并发读写同一快照根目录。
删除源文件后,为什么历史快照里还有
这是预期行为。新的 daily.0 可以反映源端删除,但旧的 daily.1、weekly.0 本来就是历史版本,直到超出保留数量才会被轮转删除。
不要手动进入旧快照逐个删除文件来“同步状态”。这会破坏历史保留的意义,也可能误删仍通过硬链接共享的数据入口。
如何确认备份真的可恢复
至少每月抽样完成一次恢复:
- 从 daily、weekly 或 monthly 中选择一个快照;
- 把若干不同类型文件复制到独立临时目录;
- 核对文件大小、校验和和可打开性;
- 对 Git 裸仓库运行一致性检查;
- 记录恢复时间和发现的问题。
Git 裸仓库可抽查:
|
|
只有定时任务成功日志还不够。真正的验收标准是能从指定历史点恢复出正确、可用的数据。
一份可落地的组合配置
下面示例同时备份本机、远程 Linux、Git 裸仓库、Windows 共享和 NAS NFS。请确认代码块中的列为 Tab:
|
|
上线顺序应固定为:
|
|
逐项确认:
- 快照根目录位于正确的备份盘;
- SMB 和 NFS 共享真实挂载且可读;
- SSH 连接不需要交互;
- dry-run 没有意外来源或目标;
.git过滤结果只包含预期目录;daily.0中能找到所有关键文件;- 第二次快照的未变化文件使用硬链接;
- 恢复测试能够成功打开文件。
最后再启用 cron。这样出现问题时,可以明确区分配置语法、SSH、共享挂载、源权限、磁盘容量和定时环境,而不会把所有错误都归到 rsnapshot。