我想通过调用ssh上的tar脚本来备份我的系统,该脚本通过管道返回到stdout,以便ssh启动主机存储tar。
但是,我想对在该主机上运行的一些服务执行逻辑转储,但那里没有足够的磁盘空间将这些巨大的文件转储到磁盘上,然后从tar捕获它们。
我知道tar不能处理流(或任何大小未知的文件)。所以我想,我在运行到固定大小的块时split
转储,将它们临时存储在磁盘上,将它们带到tar
进行处理,然后在处理下一个块之前删除它们。
我的脚本看起来像这样:
mkfifo filenames
tar --files-from filenames -cf - &
TAR_PID=$!
exec 100>filenames
# tar all relevant host-level directories/files
echo "/etc" >&100
echo "/root" >&100
function splitfilter() {
tee $1
(
# wait for tar to finish reading the file and delete it after being processed
inotifywait -e close_nowrite $1
rm $1
) &
RM_SHELL_PID=$!
# send the filename for processing to tar
echo $1 >&100
wait $RM_SHELL_PID
}
export -f splitfilter
# perform the logical dumps of my services
dump_program_1 | split -b 4K /var/backup/PREFIX_DUMP_1_ --filter "splitfilter $FILE"
dump_program_2 | split -b 4K /var/backup/PREFIX_DUMP_2_ --filter "splitfilter $FILE"
exec 100>&-
wait $TAR_PID
rm filenames
字符串
然而,我不明白为什么这是随机的工作和不。到目前为止,我观察到了两种不同的失效行为:
- 焦油没有停止。在脚本的最后,我关闭了文件描述符,所以我希望fifo向tar发送EOF信号。这应该会很快结束tar进程,因为它只需要完成最后4k块的处理(如果还没有完成的话)。我无法解释为什么它会随机挂起。最终生成的存档实际上是完整的(除了tar的EOF标记)...
- tar处理0字节文件。经过一段时间的处理后,
inotifywait
似乎在tar关闭块文件以供阅读之前唤醒。从而导致文件被删除,从而在存档中显示为0字节大小的条目。我已经通过在echo $1 >&100
调用后放置一个sleep 1
来缓解这种情况。在那之后,前几个块实际上会被填满,但是运行一段时间后,后面的块又变成了0大小。我感觉到时间问题在这里的某个地方,但目前看不出来。
经过一天的调试,我对这种方法失去了希望,但如果它能可靠地工作,那就太好了:居然能产生流状焦油!别误会我的意思它在调试时工作了一两次。我就是不明白为什么不总是
1条答案
按热度按时间wixjitnu1#
tar格式相当简单。我们可以自己用这个TXR Lisp程序来传输它。
警告:这不能处理长路径;它为每个对象只输出一个头块。
备份列表由路径和命令条目混合组成。
命令被执行,它们的输出被切成4K的片段,这些片段成为编号的文件。这些都是删除,因为我们去,所以没有积累。
即使在我们编写自己的tar实现时,我们仍然必须这样做,因为该格式要求预先知道每个对象的大小并将其放置在头中。没有办法将任意长的命令输出作为tar流进行流式传输。
字符串
我没有一个回归测试套件;我手动测试了它,方法是将各种类型的单个对象存档,并将十六进制转储与GNU tar进行比较,然后解包由该实现存档的目录树,并对原始树进行递归差异。
但是,我想知道您正在使用的备份服务是否无法处理连锁存档。如果它处理链接的归档,那么您可以使用
tar
的多个调用来生成流,而不会有所有这些进程协调问题。对于一个tar消费者来说,要处理连锁的归档,它只需要忽略全零块(不把它们当作归档的结尾),但是继续阅读。
如果备份服务是这样的,那么你基本上可以这样做:
型
我在GNUTar中看不到任何不写终止零的选项。也许可以写一个过滤器来消除这些:
型
尚未写入的
remove-zero-blocks
过滤器,通过面向块的FIFO读取512字节块,该FIFO足够长,可以覆盖tar
使用的分块因子。它将新读取的缓冲区放入FIFO的一端,并写入从另一端碰撞的最旧缓冲区。当遇到EOF时,FIFO被刷新,但是所有为零的尾部512字节块被省略。这应该会击败拒绝忽略零块的备份服务。