目标
我想使用太小而无法存储所有内容的磁盘来创建大型文件池的备份。
情况描述
我有一台带 RAID 的 NAS/家庭服务器(运行 Ubuntu 18.04)。RAID 的容量比我拥有的任何外部硬盘都大得多,我想用它来备份 RAID 上的内容。
当前方法
我目前的做法是尝试手动找到尽可能少的目录结构子树,使其略低于其中一个驱动器的容量,然后通过以下方式计算每个文件的校验和
find /path/to/subtree/ -type f -print0 | sort -z | xargs -r0 sha256sum > sha256sumsBeforeCopying
,通过以下方式复制文件
cp -a origin destination
,复制完成后验证并保存校验和。
我还尝试以某种方式执行此操作,以确保我仍然有一个不同的驱动器,其中包含我当前正在复制的子树的旧副本,因为我在执行上述过程之前清除了驱动器。
问题
这当然是一个耗时的过程。我怎样才能更有效地实现将数据备份到许多小驱动器上的目标呢?
答案1
由于您可以同时连接所有驱动器,因此最简单的选择似乎是使用mergerfs
允许您合并多个文件系统的。基本概念来自man mergerfs
:
怎么运行的
mergerfs 在逻辑上将多个路径合并在一起。想象成集合的并集。[...]
A + B = C /disk1 /disk2 /merged | | | +-- /dir1 +-- /dir1 +-- /dir1 | | | | | | | +-- file1 | +-- file2 | +-- file1 | | +-- file3 | +-- file2 +-- /dir2 | | +-- file3 | | +-- /dir3 | | +-- file4 | +-- /dir2 | +-- file5 | | +-- file6 | +-- file4 | +-- /dir3 | | | +-- file5 | +-- file6
当多个驱动器中出现相同的文件路径、权限策略等时,会出现几种情况,但由于您假设备份到空驱动器集,所以这并不真正相关,使用默认设置即可。
怎么做:
1)假设您有三个外部驱动器,每个驱动器都有一个分区:sdb1,sdc1,sdd1
只需像平常一样安装它们:
mkdir /mnt/sd{b,c,d}1
for drive in sd{b,c,d}1 ; do mount /dev/$drive /mnt/$drive ; done
2)创建一个组合空间并将驱动器“安装”到组合 FS 中
mkdir /mnt/merged
mergerfs -o fsname=mergerFS /mnt/sdb1:/mnt/sdc1:/mnt/sdd1 /mnt/merged
句法mergerfs -o <options> <colon:separated:list:of:sources> <target>
可以跳过选项,因为默认设置就可以,但是指定一个伪文件系统名称以便在输出中快速找到它似乎很好df
。
3)仅用/mnt/merged
作备份位置并验证您的备份。
4)完成后,您可以通过卸载等方式拆卸合并的驱动器
umount /mnt/merged
现在您将在不同的驱动器中找到文件,但不应拆分任何文件。各个驱动器仍可独立完全发挥作用。
值得注意的mergerfs
是fuse
,因此即使非 root 用户也可以合并和取消合并,从而允许维护标准用户的读/写权限。
mergefs /media/john/drive1:/media/john/drive2 /home/john/merged_drive
fusermount -u /home/john/merged_drive
也可以合并多个 FS 类型,但我无法判断对不同 FS 的写入操作是否安全。不过,这应该不成问题,因为我希望您肯定会拥有具有相同 FS 的所有备份驱动器。
mergerfs
应该在大多数发行版的标准存储库中可用。
编辑:旁注 - 源不一定必须是完整的驱动器,但可以是目录。
答案2
这个低级且经常被低估的tar
命令(至少是 GNU tar)似乎运行得很好。
我尝试在一个 30+MB 的目录中使用每个 tar 文件 10MB 的限制,提供以下名称:下一个通过列表打开 tar 文件。(提示仍然会出现,但没有换行符,因此您会看到一长行提示符,但除了视觉上不协调之外,似乎没有什么坏处。因此,在下面的输出中,我添加了一个换行符,以使 wc 的输出显示得更清晰)。
$ ls -al file*tar
ls: cannot access 'file*tar': No such file or directory
$ cat list # notice list starts from file2, because the tar command itself starts with file1
n file2.tar
n file3.tar
n file4.tar
$ tar -cf file1.tar -M -L 10M t/ < list
Prepare volume #2 for ‘file1.tar’ and hit return: Prepare volume #3 for ‘file2.tar’ and hit return: Prepare volume #4 for ‘file3.tar’ and hit return: %
$ ls -al file*tar
-rw------- 1 ff ff 10485760 Dec 3 10:02 file1.tar
-rw------- 1 ff ff 10485760 Dec 3 10:02 file2.tar
-rw------- 1 ff ff 10485760 Dec 3 10:02 file3.tar
-rw------- 1 ff ff 1392640 Dec 3 10:02 file4.tar
$ tar -tf file1.tar -M < list | wc
Prepare volume #2 for ‘file1.tar’ and hit return: Prepare volume #3 for ‘file2.tar’ and hit return: Prepare volume #4 for ‘file3.tar’ and hit return:
30 74 1106