11.3. 備份程式

三個主要的備份程式: dump(8)tar(1)、 和 cpio(1)

11.3.1. Dump 和 Restore

dump(8)restore(8) 是 UNIX 傳統的備份程式。它以 block 為單位來備份資料,而不是以檔案,link 或目錄來備份資料。 dump(8) 備份的是 device,整個 filesystem,不能只備份一個 filesystem 的部份或是用到兩個以上 filesystem 的 directory tree, 若是遇到 soft link ln(1) 或是 mounting point ,則只會記錄下 building block。dump(8) 出現於 ATT UNIX 的 Version 6 (約 1975) 。預設的參數適用於 9-track 磁帶(6250 bpi),所以如果要用高密度的磁帶 (最高可達 62.182 ftpi),就不能用預設的參數,而要另外指定參數。

rdump(8)rrestore(8) 透過網路, 在另一台電腦的磁帶機上備份資料。這兩個程式都是藉著 rcmd(3)ruserok(3) 來存取遠端的磁帶機。因此, 執行備份的使用者必需要有遠端主機的rhosts 存取權。rdump(8)rrestore(8) 的參數必需適用於遠端主機 (例如,當你從 FreeBSD 連到一台 Sun 工作站 komodo 去使用磁帶機時,使用 /sbin/rdump 0dsbfu 54000 13000 126 komodo:/dev/nrsa8 /dev/rda0a 2>&1) 。 要注意的是,你必需考量你的狀況,因為執行遠端命令會牽涉到"安全" (security)的問題(意指資料的安全性)。

11.3.2. Tar

tar(1) 同樣是在 ATT Unix Version 6 (約 1975)時出現的。 tar(1) 可以直接對 filesystem 做處理: 它直接將檔案和目錄寫到磁帶上, tar(1) 不支援像 cpio(1) 那樣多的選項,但 tar(1) 不需要用像 cpio(1) 那樣奇怪的 command pipeline。

許多版本的 tar(1) 不支援透過網路備份,而 GNU 版的 tar(1) (FreeBSD 用的就是 GNU 版的) 提供相同於 rdump(8) 的參數來使用遠端的裝置。例如要 tar(1) Sun 工作站 komodo 上一台 Exabyte 磁帶機,就使用: /usr/bin/tar cf komodo:/dev/nrsa8 . 2>&1。 對於不支援遠端裝置的 tar(1) ,可以使用一個pipeline 和 rsh(1) 來傳送資料給遠端的磁帶機。

    # tar cf - . | rsh hostname dd of=tape-device obs=20b

If you're worried about the security of backing over a network you should use the ssh(1) command instead of rsh(1).

11.3.3. Cpio

cpio(1) 是 Unix 最早用來做檔案交換的磁帶機程式。它具有做 byte-swapping 的選項,可以用數種不同的格式寫入,並且可以將資料 pipe 給其他程式。cpio(1) 沒辦法自動搜尋 directory tree 內的檔案列表,必須經由標準輸入 (stdin)來指定。

cpio(1) 不支援透過網路的備份方式。你可以使用 pipeline 和 rsh(1) 來傳送資料給遠端的磁帶機。

11.3.4. Pax

pax(1) 是 IEEE/POSIX 對於 tar(1)cpio(1) 的回應。由於多年來各種不同版本的 tar(1)cpio(1) 間的不相容,為了防止這種情形,並使其標準化,POSIX 出了這套新的工具程式。pax(1) 嘗試可以讀寫各種 cpio(1)tar(1) 的格式,並可以自己增加新的格式。它的命令較類似 cpio(1)

11.3.5. Amanda

Amanda (Advanced Maryland Network Disk Archiver) 並非單一的程式, 而是一個主從式 (client/server) 的備份系統。 一台 Amanda server 可以備份任意數量,執行 Amanda client , 或是連上 Amanda server 的電腦上的資料於一台磁帶機上。 一個常見的問題是,將資料寫入磁帶機的時間, 超過取得資料的時間,而 Amanda 解決了這個問題。它使用一個 "holding disk" 來同時備份數個 filesystem。 Amanda 建立 "archive sets":一組磁帶,用來備份在 Amanda 的組態檔中所列出的完整的 filesystem。

Amanda 組態檔提供完整的備份控制及 Amanda 產生的網路傳輸。 Amanda 可以使用上述任何一個備份程式來寫入磁帶。 Amanda 可能是以 port 或 package 被取得,並非系統預設就有的。

11.3.6. Do Nothing

"Do nothing" 不是一個程式, 而是最被廣泛使用的備份策略。不需要預算,不需要備份的計畫表, 全部都不用。如果你的資料發生了什麼問題,忽略它,並且忍受它!

假如你的時間和資料不值得你做這些事,那麼 "Do nothing" 將是你最好的備份程式。要注意的是,Unix 是相當好用的工具,你可能在數個月內,就發現你已經收集了不少, 對你而言,相當具有價值的東西。

"Do nothing" 對於像 /usr/obj 或其他可由你的電腦產生的檔案而言,是最好的方法。例如你從 SGML 檔所產生的 HTML 檔,就不需要備份,而應該備份的是 SGML 檔。

11.3.7. 哪個備份程式最好?

dump(8) 時期 ,Elizabeth D. Zwicky 測試了所有以上所列出的備份程式。在各式各樣,怪異的 filesystem 中, dump(8) 是你明智的抉擇。Elizabeth 建立起各式各樣,奇怪,正常的 filesystem,並用各種備份程式,測試在各種 filesystem 上備份及回存資料。這些怪異之處包括了:具有 hole 和一個 null block 的檔案,檔名具有 funny character,無法讀寫的檔案及裝置, 在備份時改變檔案大小,在備份時建立或刪除的檔案。她將結果刊出在 LISA V in Oct. 1991. torture-testing Backup and Archive Programs

11.3.8. 遇到狀況的回存程序

11.3.8.1. 在災難之前

在遇到任何的災難之前,你只需要做以下四個步驟:

第一,印出你的每個磁碟機代號 (例如: disklabel da0 | lpr),檔案系統表 (/etc/fstab) ,以及所有的開機訊息,並保留兩份。

第二,確定遇到狀況時,用來開機及修復的軟碟 (boot.flpfixit.flp) 具有你所有的裝置代號(並且能夠使用)。最簡單的方法是用軟碟開機, 然後檢查開機訊息,如果你的裝置都有被列出,並且可以正常使用, 就可以跳到第三步了。

否則,你必須建立兩張傳統的可開機軟碟,並包含 fdisk(8)disklabel(8)newfs(8)mount(8)、 以及你所使用的備份程式。這些程式必需被靜態連結。如果你使用的是 dump(8),那麼這張軟碟就必需包含 restore(8)

第三,定期將資料備份到磁帶。 任何在你上次備份之後的改變都無法恢復。記得將磁帶防寫。

第四,測試你在第二步所建立的軟碟及備份的磁帶,將過程記錄下來, 並和這張可開機的軟碟,磁帶放在一起。也許你在回存時會想要抓狂, 而這份記錄將防止你破壞你的磁帶(怎麼說呢?因為你可能將 tar xvf /dev/rsa0 打成 tar cvf /dev/rsa0 而覆寫了你的備份磁帶)。

為了安全,你可以每次都做兩份備份磁帶及一張開機磁片, 並將其中一份備份磁帶存放在遠方。遠方不是指同一棟辦公大樓的地下室 (世貿中心的一些公司行號應該學到了一些教訓), 而是真的要讓你的磁帶離你的電腦遠遠的。

以下是一個建立開機磁碟的 shell script 範例:

    #!/bin/sh
    #
    # create a restore floppy
    #
    # format the floppy
    #
    PATH=/bin:/sbin:/usr/sbin:/usr/bin
    
    fdformat -q fd0
    if [ $? -ne 0 ]
    then
    	 echo "Bad floppy, please use a new one"
    	 exit 1
    fi
    
    # place boot blocks on the floppy
    #
    disklabel -w -B /dev/rfd0c fd1440
    
    #
    # newfs the one and only partition
    #
    newfs -t 2 -u 18 -l 1 -c 40 -i 5120 -m 5 -o space /dev/rfd0a
    
    #
    # mount the new floppy
    #
    mount /dev/fd0a /mnt
    
    #
    # create required directories 
    #
    mkdir /mnt/dev
    mkdir /mnt/bin
    mkdir /mnt/sbin
    mkdir /mnt/etc
    mkdir /mnt/root
    mkdir /mnt/mnt			# for the root partition
    mkdir /mnt/tmp
    mkdir /mnt/var
    
    #
    # populate the directories
    #
    if [ ! -x /sys/compile/MINI/kernel ] 
    then
    	 cat << EOM
    The MINI kernel does not exist, please create one.
    Here is an example config file:
    #
    # MINI -- A kernel to get FreeBSD on onto a disk.
    #
    machine		"i386"
    cpu		"I486_CPU"
    ident		MINI
    maxusers	5
    
    options		INET			# needed for _tcp _icmpstat _ipstat
    					 #            _udpstat _tcpstat _udb
    options		FFS			#Berkeley Fast File System
    options		FAT_CURSOR		#block cursor in syscons or pccons
    options		SCSI_DELAY=15		#Be pessimistic about Joe SCSI device
    options		NCONS=2		#1 virtual consoles
    options		USERCONFIG		#Allow user configuration with -c XXX
    
    config		kernel	root on da0 swap on da0 and da1 dumps on da0
    
    controller	isa0
    controller	pci0
    
    controller	fdc0	at isa? port "IO_FD1" bio irq 6 drq 2 vector fdintr
    disk		fd0	at fdc0 drive 0
    
    controller	ncr0
    
    controller	scbus0
    
    device		sc0	at isa? port "IO_KBD" tty irq 1 vector scintr
    device		npx0	at isa? port "IO_NPX" irq 13 vector npxintr
    
    device		da0
    device		da1
    device		da2
    
    device		sa0
    
    pseudo-device	loop		# required by INET
    pseudo-device	gzip		# Exec gzipped a.out's
    EOM
    	 exit 1
    fi
    
    cp -f /sys/compile/MINI/kernel /mnt
    
    gzip -c -best /sbin/init > /mnt/sbin/init
    gzip -c -best /sbin/fsck > /mnt/sbin/fsck
    gzip -c -best /sbin/mount > /mnt/sbin/mount
    gzip -c -best /sbin/halt > /mnt/sbin/halt
    gzip -c -best /sbin/restore > /mnt/sbin/restore
    
    gzip -c -best /bin/sh > /mnt/bin/sh
    gzip -c -best /bin/sync > /mnt/bin/sync
    
    cp /root/.profile /mnt/root
    
    cp -f /dev/MAKEDEV /mnt/dev
    chmod 755 /mnt/dev/MAKEDEV
    
    chmod 500 /mnt/sbin/init
    chmod 555 /mnt/sbin/fsck /mnt/sbin/mount /mnt/sbin/halt
    chmod 555 /mnt/bin/sh /mnt/bin/sync
    chmod 6555 /mnt/sbin/restore
    
    #
    # create the devices nodes 
    #
    cd /mnt/dev
    ./MAKEDEV std
    ./MAKEDEV da0
    ./MAKEDEV da1
    ./MAKEDEV da2
    ./MAKEDEV sa0
    ./MAKEDEV pty0
    cd /
    
    #
    # create minimum filesystem table
    #
    cat > /mnt/etc/fstab <<EOM
    /dev/fd0a	/	ufs	rw 1 1
    EOM
    
    #
    # create minimum passwd file
    #
    cat > /mnt/etc/passwd <<EOM
    root:*:0:0:Charlie &:/root:/bin/sh
    EOM
    
    cat > /mnt/etc/master.passwd <<EOM
    root::0:0::0:0:Charlie &:/root:/bin/sh
    EOM
    
    chmod 600 /mnt/etc/master.passwd
    chmod 644 /mnt/etc/passwd
    /usr/sbin/pwd_mkdb -d/mnt/etc /mnt/etc/master.passwd
    
    #
    # umount the floppy and inform the user
    #
    /sbin/umount /mnt
    echo "The floppy has been unmounted and is now ready."

11.3.8.2. 災難之後

主要的問題在於:你的硬體還存活著嗎? 由於你已經做好定期的備份工作,所以你不必擔心軟體的問題。

假如你的硬體已經損毀,首先,你必須先將已損毀的硬體更換掉。

如果你的硬體沒有問題,再檢查一下你的軟碟。 如果你用的是傳統的開機磁片,以 single-user (在出現 boot: 後鍵入 -s), 並跳過下面這段。

如果你使用的是具有 boot.flpfixit.flp 的開機磁片,把這段看完。首先, 用這張磁片開機。當螢幕出現安裝選單時,選擇 Fixit--Repair mode with CDROM or floppy.。根據螢幕的提示,插入有 fixit.flp 的磁片, restore,其他你需要用到的程式就會出現在 /mnt2/stand

分別修復每一個檔案系統。

試著 mount(8) 你的第一個磁碟的 root partition (例如:mount /dev/da0a /mnt)。 假如這個磁碟代號已經毀損,使用 disklabel(8) 來重新分割並重新分配磁碟代號(利用你之前所保留下來的資料)。 使用 newfs(8) 來建立檔案系統,並重新 mount 軟碟 read-write 的 root partition(mount -u -o rw /mnt)。 然後使用你的備份程式及備份磁帶來修復檔案系統 (例如: restore vrf /dev/sa0)。Unmount 這個檔案系統 (例如:umount /mnt) 。 對於每個毀損的檔案系統都重覆一次。

當你的系統正常開啟之後,將你的資料備份到新的磁帶。 任何造成資料遺失的災難都可能再次發生。現在花一些時間, 也許可以使你免於下次的難過。