用 rsync 指令備份和還原 Debian GNU/Linux 10 作業系統
【摘要】敘述用 rsync 指令備份和還原 GNU/Linux 作業系統的方法,來源包括使用中與非使用中的系統,目標包括製成壓縮檔和到外接碟。
【目錄】
【前言】【複製】
【複製非使用中的單一分割區】
【複製非使用中的雙分割區】
【複製使用中的系統】
【備份】
【還原】
【後處理】
【後語】
【前言】
一、前面已敘述用 dd 指令備份和還原 GNU/Linux 作業系統的方法。這種方法的問題是必需複製整個分割區。也就是說,檔案以外的空白區 (free space) 也要複製。如果用 rsync
,就可以只複製檔案,以節省時間、空間。
二、兩年多前曾發表「用 rsync 複製系統」,近日在 Debian GNU/Linux 10 重新測試修改,分享於此。
三、Linux 系統的目錄可以有很多種分配方式。最單純的是把所有的目錄都放在同一個分割區。其次是兩個分割區,系統一個,HOME 一個。也有人用更多的分割區,把系統目錄分散在多個分割區。本文介紹前兩種狀況。
四、除了可以複製非使用中的系統,也可以複製正在使用的系統。下文都一併介紹。
五、所以,要複製的狀況有:
- 非使用中的單一分割區
- 非使用中的雙分割區
- 使用中的系統
六、這三種狀況都假設 sda1 是雙分割區中的系統,sda2 是其 HOME;而 sda3 是單一分割區,包括系統和 HOME 目錄。複製和還原的目標分割區都是外接碟的第一分割區 sdb1。
【複製】
【複製非使用中的單一分割區】
一、掛載來源分割區
用 sda1 和 sda2 開機,待複製的來源分割區是 sda3,把它掛在 /media/sda3:
sudo mkdir /media/sda3 sudo mount /dev/sda3 /media/sda3
二、格式化目標分割區
插入外接裝置可能會自動掛載,若目標分割區 sdb1 已掛載,需先卸下:
sudo umount /dev/sdb1
如果 sdb1 尚未格式化:
sudo mkfs.ext4 -F /dev/sdb1
-F
:強制執行
三、掛載目標分割區
格式化 sdb1 後,即可掛上,假設是在 /mnt,此目錄必需原本是空的。
sudo mount /dev/sdb1 /mnt
四、複製
如果不是運轉中的系統,有些目錄是空的,譬如 mnt、proc、sys 等。但為了保險起見,都列入排除清單。
sudo rsync -aAX --exclude={"/dev/*","/media/*","/mnt/*","/proc/*","/run/*","/sys/*","/tmp/*","/lost+found"} /media/sda3/ /mnt
-a
、--archive
:archive 模式;等於 -rlptgoD
(無 -H
、-A
、-X
)
-r
、--recursive
(包括子目錄)
-l
、--links
(將 symlinks 視為 symlinks)
-p
、--perms
(保留 permissions)
-t
、--times
(保留修改時間)
-g
、--group
(保留 group)
-o
、--owner
(保留 super-user)
-D
:等於 --devices
和 --specials
--devices
(保留 device files)
--specials
(保留 special files)
-A
, --acls
(保留 ACLs)
-X
, --xattrs
(保留延伸屬性)
--exclude
(列舉欲排除的 regexp)
/media/sda3/
:來源;不要漏掉最後的斜線
/mnt
:目標;最後有無斜線都一樣
五、接下來可以:
- 壓縮成備份檔保存;日後,備份檔可以還原
- 複製或還原的分割區經後處理以後,可以用來開機
【複製非使用中的雙分割區】
用 sda3 開機,而待複製的來源系統在 sda1,其 HOME 在 sda2。目標是已格式化的 sdb1。
一、掛載系統
sudo mkdir /media/sda1 sudo mount /dev/sda1 /media/sda1
二、掛載 HOME
sudo mount /dev/sda2 /media/sda1/home
三、掛載目標分割區
將 sdb1 掛在 /mnt:
sudo mount /dev/sdb1 /mnt
若 sdb1 已掛載在某目錄,以下指令要自行修改目標目錄;或是將之卸下,再掛在 /mnt。
四、複製:
如果不是運轉中的系統,有些目錄是空的,譬如 mnt、proc、sys 等。但為了保險起見,都列入排除清單。
sudo rsync -aAX --exclude={"/dev/*","/media/*","/mnt/*","/proc/*","/run/*","/sys/*","/tmp/*","/lost+found"} /media/sda1/ /mnt
-a
、--archive
:archive 模式;等於 -rlptgoD
(無 -H
、-A
、-X
)
-r
、--recursive
(包括子目錄)
-l
、--links
(將 symlinks 視為 symlinks)
-p
、--perms
(保留 permissions)
-t
、--times
(保留修改時間)
-g
、--group
(保留 group)
-o
、--owner
(保留 super-user)
-D
:等於 --devices
和 --specials
--devices
(保留 device files)
--specials
(保留 special files)
-A
, --acls
(保留 ACLs)
-X
, --xattrs
(保留延伸屬性)
--exclude
(列舉欲排除的 regexp)
/media/sda1/
:來源;不要漏掉最後的斜線
/mnt
:目標;最後有無斜線都一樣
這會將系統 sda1 和 HOME 的 sda2 合併到同一個分割區 sdb1。
五、接下來可以:
- 壓縮成備份檔保存;日後,備份檔可以還原
- 複製或還原的分割區經後處理以後,可以用來開機
【複製使用中的系統】
一、不論系統和 HOME 是否在同一分割區,因為都已掛載,所以複製時,會全部都複製到同一個分割區。
二、掛載目標分割區
假設目標是已格式化的 sdb1,將之掛在 /mnt:
sudo mount /dev/sdb1 /mnt
若 sdb1 已掛載在某目錄,以下指令要自行修改目標目錄;或是將之卸下,再掛在 /mnt。
三、複製
sudo rsync -aAX --exclude={"/dev/*","/media/*","/mnt/*","/proc/*","/run/*","/sys/*","/tmp/*","/lost+found"} / /mnt
-a
、--archive
:archive 模式;等於 -rlptgoD
(無 -H
、-A
、-X
)
-r
、--recursive
(包括子目錄)
-l
、--links
(將 symlinks 視為 symlinks)
-p
、--perms
(保留 permissions)
-t
、--times
(保留修改時間)
-g
、--group
(保留 group)
-o
、--owner
(保留 super-user)
-D
:等於 --devices
和 --specials
--devices
(保留 device files)
--specials
(保留 special files)
-A
, --acls
(保留 ACLs)
-X
, --xattrs
(保留延伸屬性)
--exclude
(列舉欲排除的 regexp)
/
:來源,即正在運轉的系統
/mnt
:目標;最後有無斜線都一樣
四、接下來可以:
- 壓縮成備份檔保存;日後,備份檔可以還原
- 複製或還原的分割區經後處理以後,可以用來開機
【備份】
若想將複製好的內容壓縮成備份檔,至少有兩種方法。
方法一:一步驟,直接用 tar
指令的壓縮選項
cd /mnt sudo tar --create --xz --file $HOME/backup.tar .
--create
:建立新 archive
--xz
:用 xz 格式壓縮
--file
:使用的檔案(不要用目前目錄 /mnt,不然會自己備份自己),backup.tar
是輸出檔名,自己訂
.
:目前目錄 /mnt
方法二:兩步驟,先製成檔案包才壓縮
sudo tar --create /mnt | xz > $HOME/backup.xz
--create
:建立新 archive
backup.xz
是輸出檔名,自己訂
【還原】
一、如果要把備份檔還原到一空白、已格式化的分割區(假設是 sdb1),依備份方法之不同而有兩法。
先掛上 sdb1:
sudo mount /dev/sdb1 /mnt
若用方法一備份:
sudo tar --extract --file $HOME/backup.tar --directory=/mnt
--extract
:抽出
--file
:使用的檔案,backup.tar
是來源檔名
--directory
:操作目錄,此處指目標
若用方法二備份:
xz -cd backup.xz | sudo tar --extract --directory=/mnt --strip-components=1
或
xz -cd backup.xz | sudo tar --extract --directory=/
-c
:輸出到 standard output
-d
:解壓縮(Decompress)
backup.xz
:備份檔的檔名
--extract
:抽出
--directory
:操作目錄,此處指目標
--strip-components=1
:去除第一層目錄
會有這兩個不同的方法是因為前一節方法二壓縮後的檔案結構是 /mnt/mnt/*,而非 /mnt/*。較合邏輯的應是第一個方法,因為是在掛載 sdb1 的 /mnt 目錄操作,將多的第一層目錄去掉。第二個方法可以說是 workaround (變通的方法)。前一節方法一壓縮後的檔案結構是 /mnt/*,所以沒有這個問題。
二、然後,後處理成可以開機。
【後處理】
複製或還原的分割區(假設是 sdb1)還要稍加處理才能用來開機。
一、掛載
sudo mount /dev/sdb1 /mnt
二、修改 fstab 檔
㈠ 不同的分割區需有不同的 UUID,剛複製來的檔案系統還是用來源分割區的 UUID,所以要改成目標分割區的 UUID。
㈡ /mnt/etc/fstab 記錄著檔案系統的配置,每一項有六個欄位,用空白分開:
<file system> <mount point> <type> <options> <dump> <pass>
接下來第一個是系統 root 的內容,例如:
#/ was on /dev/sda1 during installation UUID=11111111-1111-1111-1111-111111111111 / ext4 errors=remount-ro 0 1
UUID 後的 8-4-4-4-12 十六進位碼即是 Universally Unique IDentifier。
sdb1 的 UUID 可以用 sudo blkid
指令得知,把它換上。
㈢ 如果來源系統是雙分割區的狀況,會有下例的內容:
#/home was on /dev/sda2 during installation UUID=22222222-2222-2222-2222-222222222222 /home ext4 defaults 0 2
這要刪掉,因為在 sdb1 已合成一個。
㈣ 其他分割區,如果不對,也要修改。
三、安裝 Grub
sudo grub-install --boot-directory=/mnt/boot /dev/sdb
--boot-directory
:指定開機檔所在的目錄。
最後一項是要用來開機的裝置;提醒:此處是 sdb
而非 sdb1
。
四、更新 Grub
接下來要改 sdb1 的開機清單,必需在 sdb1 做。但是不用 sdb1 開機而要讓系統認為是用 sdb1 開機,必需用模擬的方式,所以掛上一些模擬要用的目錄。
sudo mount --bind /dev /mnt/dev sudo mount --bind /sys /mnt/sys sudo mount --bind /proc /mnt/proc
切換到 sdb1:
sudo chroot /mnt
更新 sdb1 的開機清單:
sudo update-grub
應該可以用 sdb1 開機了。
【後語】
用自製的 FluxBox Debian GNU/Linux 10 實測,並與用 dd 備份的數據比較,結果如下表:
項目 | 用 rsync 方法一 | 用 rsync 方法二 | 用 dd |
---|---|---|---|
複製+壓縮時間(分鐘) | 10+20 | 10+20 | 25 |
備份檔尺寸 | 900M | 900M | 1.2G |
還原時間(分鐘) | 20 | 8 | 7 |
註:
此系統用 dd
處理前,分割區縮小為 3900M。
備份檔是還原到隨身碟的 sdb1。