创建包含校验和的 tar 文件

waz*_*oox 18 linux archive checksum

这是我的问题:我需要将大量(最多 60 TB)大文件(通常每个 30 到 40 GB)归档到 tar 文件。我想在归档之前对这些文件进行校验和(md5、sha1 等);然而,不是读取每个文件两次(一次用于校验和,两次用于 tar'ing)或多或少是实现非常高的归档性能的必要条件(LTO-4 需要 120 MB/s 的持续速度,并且备份窗口是有限的)。

所以我需要一些方法来读取文件,在一侧提供校验和工具,并在另一侧构建一个 tar 到磁带,一些东西:

tar cf - files | tee tarfile.tar | md5sum -
Run Code Online (Sandbox Code Playgroud)

除了我不想要整个存档的校验和(这个示例 shell 代码就是这样做的),而是存档中每个单独文件的校验和。

我研究过 GNU tar、Pax、Star 选项。我查看了Archive::Tar的来源。我认为没有明显的方法可以实现这一目标。看起来我必须用 C 或类似的东西手工构建一些东西才能实现我需要的东西。Perl/Python/etc 根本不会在性能方面削减它,并且各种 tar 程序错过了必要的“插件架构”。在我开始代码改动之前,有没有人知道任何现有的解决方案?

bk.*_*bk. 17

在继续重写 tar 之前,您可能想要分析读取数据两次的快速简便方法,因为它可能不会比一次读取慢多少。

这里实现了两遍方法:

http://www.g-loaded.eu/2007/12/01/veritar-verify-checksums-of-files-within-a-tar-archive/

单线:

  tar -cvpf mybackup.tar myfiles/| xargs -I '{}' sh -c "test -f '{}' && 
  md5sum '{}'" | tee mybackup.md5
Run Code Online (Sandbox Code Playgroud)

虽然 md5sum 确实与 tar 并行地从磁盘读取每个文件,而不是通过管道传输数据,但 Linux 磁盘缓存应该使第二次读取成为从内存缓冲区的简单读取,这应该不会比真正慢标准输入读取。你只需要确保你的磁盘缓存中有足够的空间来存储足够的每个文件,第二个读取器总是从缓存中读取并且不会落后太多而不得不从磁盘中检索

  • 它实际上工作得很好,它看起来受到 CPU 处理 md5 的能力的限制(单核上大约 280MB/s)。 (3认同)

小智 5

下面是一个 Python 脚本示例。它在将文件添加到存档时计算文件的校验和。在脚本末尾,校验和文件将添加到存档中。

import hashlib,os
import tarfile
def md5(filename):
    ''' function to get md5 of file '''
    d = hashlib.md5()
    try:
        d.update(open(filename).read())
    except Exception,e:
        print e
    else:
        return d.hexdigest()

root="/home"
outtar=os.path.join(root,"path1","output.tar")
path = os.path.join(root,"path1")
chksum_file=os.path.join(root,"path","chksum.txt")
tar = tarfile.open(outtar, "w")
o_chksum=open(chksum_file,"w")
for r,d,f in os.walk(path):
    for files in f:
        filename=os.path.join(r,files)
        digest="%s:%s"%(md5(filename) , filename)
        o_chksum.write(digest+"\n")
        tar.add(os.path.join(r,files))

tar.add(chksum_file)
tar.close()
o_chksum.close()
Run Code Online (Sandbox Code Playgroud)

解压时,使用 chksum_file 来验证校验和