让我们进行以下任务:
- 在 Linux 上备份大量(例如 500GB)的小文件(几 kB 到 1MB)
- 备份存储是大多只读
- 存储速度足够快,可以访问常规目录/文件视图中的特定文件,理想情况下是通过常规文件管理器(如 mc、TotalCommander(通过 samba)等)中的内置或插件功能
- 存储最好只是单个文件(可以有效地移动到 nas 等)
- 无需压缩
- 添加文件可能是一个代价高昂的操作(即使是初始存储初始化)
我尝试了普通的旧方法tar
,但“打开”500G 的索引似乎无止境 - 所以我可能需要将其作为一个整体提取。例如,有没有办法将dd
文件系统的一部分放入映像中然后挂载它?
有什么想法吗?
答案1
您确实可以创建一个文件并将其视为块设备。不过您可能需要手动挂载它。
- 第一步是创建“块设备”——您可以使用
dd
(例如dd if=/dev/zero of=/path/to/file.name bs=100M count=6000
)或其他工具(fallocate
,truncate
)来执行此操作。 - 然后,您可以使用类似以下命令来格式化设备
mkfs.ext4 /path/to/file.name
。 - 接下来安装它-
mkdir /mntpoint; moint /path/to/file.name /mntpoint
。 - 使用您喜欢的工具将文件复制到
/mntpoint
– 例如rsnapshot
,rsync
或普通的cp
。 - 完成后卸载 – 确保您不在目录
/mntpoint
中umount /mntpoint
。
答案2
在需要快速访问备份内容的情况下,我会使用带选项的增量备份rsync
。--link-dest=
它
运行速度非常快,不会影响以前的备份副本(您可以拥有任意数量的备份副本),并且备份不会占用太多空间,因为备份副本是现有文件的硬链接。在这种情况下,可以即时访问备份,并且实际文件传输只需几秒钟,即使是大量文件,因为rsync
只复制了新文件。
#!/bin/sh
srcDir='/importunt/data' # Use full path
bkpDir='/backups' # Use full path
cd "${bkpDir}"
previousDir="$(ls -td -- */ | head -n 1 | awk -F'/' '{print $1}')" # Get most newest directory
currentDir="$(date '+%Y-%m-%dT%H;%M;%S')"
[ -n "${previousDir}" ] && {
rsync_opts="-aPvz --safe-links --link-dest=${bkpDir}/${previousDir} --exclude=*.mp3"
} || {
rsync_opts="-aPvz --safe-links --exclude=*.mp3"
}
mkdir -m 770 "${currentDir}"
rsync ${rsync_opts} "${srcDir}" "${bkpDir}"/"${currentDir}"
基本上,这样的解决方案会及时创建精确的快照,因此文件恢复非常容易。
du
如果您在目录上使用时发现每次更新时大小都在增加,请不要害怕,/backups
如果您使用,df
您会发现实际空间并没有减少。这就是 Linux 和 FreeBSD 上硬链接的计算方式,所以不用担心。为了确保我没有撒谎,您可以使用在增量备份中检查某个文件的 inode ls -i file
。您会发现所有目录中的相同文件具有相同的 inode,这意味着rsync
仅重复具有硬链接的文件名,但所有文件名都指向相同的内容。
此方法的另一个优点是您可以按任何顺序删除最旧的备份目录 - 最新的、中间的或最旧的。
上述脚本是简化的示例。如果增量备份中的内容需要编辑,则您不应使用ls -t
检测备份中最新的先前目录的机制,而是将其保存${currentDir}
到某个文件并${previousDir}
在后续调用时恢复。
由于rsync
支持传输,ssh
您可以以相同的效率将增量备份移动到远程机器,唯一的更改将被同步。
答案3
tar
不会在文件的某个位置存储简明的索引(如 Zip)——而是用实体的数据来声明每个实体,因此“似乎永无止境“——您需要阅读整个文件以获取其中每个实体的列表。
如果您想轻松访问索引,您可以捕获的输出tar -cv
,并将其与档案一起存储。
tar -cv -f ./test.tar ./to_backup/ \
> index.txt
或者,如果您需要更多信息,您可以使用tar -cT ${FILE_LIST}
,它接受来自 的文件列表${FILE_LIST}
。这样,您可以使用find
来收集文件名,将每个文件的详细信息记录到您的“指数stdout
“并生成要存档的文件名tar
。
find ./to_backup/ -type f \
| tee index.txt \
| tar -cT /dev/stdin \
> ./test.tar
无需压缩,就可以很容易地将文件添加到档案中tar
(tar
代表“磁带档案“... 在磁带上移动数据是件很痛苦的事)。具有简洁索引的文件格式在以后添加文件会更加困难,尽管这通常是可能的。