更新大型壓縮文件而不創建臨時文件
我正在嘗試找出一種方法,可以在不為要壓縮的文件創建臨時文件的情況下,在 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 ish Gb)都在一個目錄中,並且文件名是 GUID,因此無法定位文件以可預見的方式。
提前感謝一些終端柔術的系統管理員!
這幾乎肯定是行不通的(更新:另見這個答案)
Zip 存檔(但與其他存檔幾乎沒有什麼變化)的建構類似於文件系統:
假設我們要在不移動 File#2 的情況下更新 File#1,並且 File#1壓縮後可能*會變大。*這將需要:
- 刪除中央標題
- 在文件#2 之後添加文件#1 數據(第二個副本)
- 再次添加 Central Header,更新 File#1 的偏移量
在 Zip 文件的開頭創建一個“死區”。可以使用該區域進一步儲存另一個文件。基本上你需要將傳入的文件壓縮成一個臨時文件,從而得到它的最終大小;有了它,您將掃描 zip 文件並尋找“漏洞”。如果存在合適的“洞”,將臨時文件複製到 zip 文件中,可能會留下一個較小的“洞”;否則,通過替換中央標題來添加它。
雖然可能,但管理 Zip 存檔中的鬆弛空間以及合併相鄰“孔”需要小心,據我所知,沒有人這樣做過(例如,我可以編寫一個與壓縮無關的實用程序來替換 Zip 中的文件文件,使用主 zip 實用程序生成新的壓縮流,並用可辨識的序列替換舊文件名以將其標記為可用空間;這將非常慢)。
最接近您想要的格式是使用完全不同的格式 - 例如,您將
btrfs
在循環設備上創建一個文件系統,將其設置為可用的最大壓縮(我相信這將是 LZO)。然後安裝循環設備並使用rsync
它來更新它。解除安裝循環設備,主機文件是一個壓縮檔案……各種各樣。根據文件的性質,您甚至可以利用btrfs
的重複數據刪除功能。壓縮文件系統的壓縮率低於 Zip,但有幾個文件(顯然是 PDF、ZIP,大多數圖像格式如 JPEG、PNG 和 GIF,現代 (Libre)Office 格式…)無法壓縮,所以這不是一個問題。由於您說未壓縮文件為 36Gb 而 Zip 為 32Gb,因此您可能處於這種情況,並且可能會從非壓縮格式中受益)。