更新大型压缩文件而不创建临时文件

更新大型压缩文件而不创建临时文件

我正在尝试找出一种方法,可以在 Linux 服务器上更新压缩文件(当前使用 zip,但也对 tar/gz/bz 衍生物开放),而无需为要压缩的文件创建临时文件。

我正在压缩整个域的目录(在任何给定时间大约为 36Gb +),并且网络服务器上的驱动器空间有限。问题是,当 zip 构建新的压缩文件时,它会创建一个临时文件,该文件可能会在完成后覆盖现有的 zip 文件,但在此过程中,源目录的 36Gb + 现有 zip 文件的 32Gb + 30 Gb 的临时文件非常接近最大化我的驱动器空间,并且在未来的某个时候,它将超出驱动器的可用空间。

目前,该目录是使用 cronjob 命令备份的,如下所示......
0 0 * * * zip -r -u -q /home/user/SiteBackups/support.zip /home/user/public_html/support/

我不想每次都删除 zip 文件,首先是因为该目录每 4 小时压缩一次,而且因为该目录太大,重新压缩整个目录而不是仅仅更新它是相当资源密集型的 -至少我相信这是真的。也许我错了?

此外,将其分解为针对不同目录的不同命令将不起作用,因为大部分数据(总共 36Gb 中的 30 Gb)都在一个目录中,并且文件名是 GUID,因此无法定位文件以可预测的方式。

预先感谢系统管理员的一些终端柔术!

答案1

这几乎肯定不会起作用(更新: 也可以看看回答)

Zip 存档(但与其他存档相比变化不大)的构建方式类似于文件系统:

拉链结构

假设我们要更新 File#1 而不移动 File#2,并且可能使用 File#1更大一旦压缩。这需要:

  • 删除中央标题
  • 在 File#2 之后添加 File#1 数据(第二个副本)
  • 再次添加中央标头,并更新 File#1 的偏移量

在 Zip 文件的开头创建一个“死区”。这将是可能的使用该区域进一步存储另一个文件。基本上,您需要将传入文件压缩到临时文件中,从而获得其最终大小;有了它,你就可以扫描 zip 文件并寻找“漏洞”。如果存在合适的“漏洞”,则复制 zip 文件内的临时文件,可能会留下一个较小的“漏洞”;否则,通过替换中央标题来添加它。

尽管可能的,管理 Zip 存档内的空闲空间以及相邻“洞”的合并需要小心,据我所知,没有人这样做过(例如,我可以编写一个与压缩无关的实用程序来替换 Zip 文件内的文件,使用主 zip 实用程序生成新的压缩流,并用可识别的序列替换旧文件名,以将其标记为可用空间;可怕地慢的)。

最接近您想要的就是使用完全不同的格式 - 例如,您可以btrfs在循环设备上创建一个文件系统,并将其设置为可用的最大压缩(我相信这将是 LZO)。然后安装循环设备并用于rsync更新它。卸载循环设备,主机文件是一个压缩档案......某种形式。根据文件性质,您甚至可以利用 的btrfs重复数据删除功能。

压缩文件系统的压缩率低于Zip,几个文件(显然是 PDF、ZIP,大多数图像格式,如 JPEG、PNG 和 GIF、现代 (Libre)Office 格式...)无法压缩,所以这不是问题。既然您说未压缩的文件是 36Gb,而 Zip 是 32Gb,那么您可能处于这种情况,并且可能会受益于非压缩的格式)。

相关内容