我在《dd:
窮人的硬碟備份與恢復工具》中分享了如何做硬碟的鏡像備份和硬碟恢復的小經驗。不過,光用dd指令做硬碟備份,那麼備份鏡像文件佔據的空間和源盤空間一模一樣。較新的機器,不少內裝的硬碟高達500GB或1TB。那麼備份USB盤就需要有相應的空間。其實,硬碟上有許多未用空間,把未用空間也原樣備份實在是資源浪費。我們不妨把鏡像備份壓縮起來。
在《
dd:
窮人的硬碟備份與恢復工具》一文中我們知道如何用
dd作鏡像備份。我們用的指令類似於:
dd
if=/dev/sda of=/media/sdc1/yourBackupDir/BACKUP.img bs=512k &
而現在,要製作壓縮鏡像備份,我們得把
dd和
gzip指令結合起來。以下是製作壓縮鏡像備份的指令:
dd
if=/dev/sda ibs=512k | gzip > /media/sdc1/yourBackupDir/backup.gz
我解釋一下指令。
if 跟隨的是輸入文件。這裡輸入文件是device下面的整個硬碟sda
這裡我們不見了of(輸出文件),而代之以另一個程序,叫gzip的壓縮程序。dd程序的輸出被送往gzip,成了gzip的輸入。通過gzip的壓縮,它的輸出被記錄在文件backup.gz中。文件backup.gz的路徑是掛載於/media下的USB硬碟sdc1的文件夾yourBackupDir。
用這個指令,可以大大減少備份的空間。我的一台
Lenovo台式電腦配備
300GB的硬碟,安裝
WINDOWS
XP、大量
Lenovo隨機軟體和小孩的遊戲軟體。經過
gzip的壓縮,備份被壓縮在
60GB左右。我自己使用的
Lenovo
S10-2 Netbook,配備
160GB硬碟,安裝
WINDOWS
XP、
Lenovo隨機軟體,
TradeStation
8,
OpenOffice,以及第二個操作系統「紅旗
Linux
6.3」。它的壓縮鏡像備份是
22.3GB。
那麼,壓縮的鏡像備份如何恢復呢?硬碟恢復的指令是:
gzip
-dc /media/sdc1/yourBackupDir/backup.gz | dd of=/dev/sda obs=512k &
這條指令的意思是:
gzip的輸入是存於硬碟
sdc1中的壓縮鏡像備份
backup.gz。
gzip
的
-d 表示解壓縮;
-c
是把輸出寫到標準輸出端(通常是屏幕)。然後把
gzip的輸出作為
dd 指令的輸入。而
dd指令的輸出則是硬碟
sda。
dd 指令的
obs=
512k
表示
dd 的輸出緩衝是
512k。就是說
dd 等待
gzip的輸入,積累到了
512k之後才向硬碟
sda寫一次。
用
dd和
gzip結合的方法壓縮的效果不錯。不過對於使用多年的機器,壓縮效果就不如新的時候那麼好了。這是為什麼呢?
我們知道,文件壓縮的原理是建立一個索引表,用較短的字元串來替代較長的字元串。比如字元串:
「This_is_a_test._This_is_a_test._This_is_a_test._This_is_a_test._」(我在這裡用_表示空格,以便看清楚)。
如果我們從左到右逐字掃描第一個重複是
is_。在索引表裡我們建立第一個替代:
1 3 3 (第一目索引從第三個位置起,長度為
3,
即
is_所在的位置)
這樣,我們的字元串就可以寫成:
「This_1a_test._This_1a_test._This_1a_test._This_1a_test._」
我們接著掃描:「
This_1a_test._」
又有重複。於是索引表就成了:
1 3 3
2 1 14 (第二目檢索從第一位起,長度為
14)
於是,字元串可以些成:
「This_1a_test._222」
然後把檢索表加在壓縮文件後面,就形成了壓縮文件。所有文件的儲存最終都是2進位制的0和1的數字,重複率很高,所以壓縮很有效。
復原時,反向運作即可復原。
當然,這只是簡單說一下無損壓縮的原理。每個壓縮軟體都有可能有不同的做法。我們用的gzip具體怎麼工作的,我也不清楚。有興趣可以查看gzip的源碼。了解原理的目的是為了說明我的應用。
在前面解釋文件壓縮原理的那個例子中,我們看到,一個文件重複的字串越多,重複的字串越長,那麼壓縮效果越好。未寫過的空間原本都是2進位的0,會有很長、很多的重複,有利於壓縮。然而,在我們使用計算機的過程中,我們不斷新建文件,不斷刪除文件,不斷把文件來回複製、刪除或下載、刪除。操作系統本身也不斷生成各種文件,用完后又刪除。這些看似被刪除的文件其實並沒有真的被刪除。操作系統只是在文件管理系統的檢索表中把文件名的頭一個字母抹掉。這樣做,一是為了刪除的操作快,二是為了萬一用戶後悔,數據可以盡可以多地恢復。操作系統在創建新的文件時,會儘可能寫在完全未被使用過的空間,而不是寫在已經抹掉的文件空間。這也是為了萬一需要被刪除的文件盡可以多地恢復。但這個做法對壓縮卻不利的因素。因為原來未寫過的空間一色清的2進位0,現在可能被各種文件寫過後,重複率降低,從而降低了壓縮的效率。
我們有沒有辦法提高壓縮效率呢?有。答案還是能在dd指令中找到。那就是,先用dd指令把硬碟所有未用空間寫成0,這樣已被刪文件的空間就重新被0佔據。這個指令是:
dd
if=/dev/zero of=/media/sda1/zerofile bs=512k
&
它會建立一個命名為zerofile的文件(你可以給任何文件名),dd會用0寫這個文件,直到這個文件佔據邏輯硬碟sda1中所有的剩餘空間,無法再寫為止。之後,刪除這個zerofile,你就把所有未用空間重新歸0了。歸0之後再作硬碟的鏡像壓縮備份,那麼備份就會小很多。