[教學]從零開始學習 rdiff-backup 使用方法

每一個系統管理員都會有自己習慣的備份工具,例如這次介紹的 rdiff-backup,就是相當熱門的增量備份(逆差異備份)工具,簡單易懂的指令界面,適合搭配 crontab 等排程工具,非常彈性。

從一個範例開始(備份)

首先建立一個資料夾,我們等一下會在裡面新增檔案,測試備份的效果:

mkdir example

把目前的日期寫入進去:

date | tee -a example/time.txt

使用 rdiff-backup 備份到 example-backup 資料夾

rdiff-backup example example-backup

可以看得出來,備份資料夾中除了原本的 time.txt 以外,多了 rdiff-backup-data 這個資料夾:

$ tree example       
example
└── time.txt

0 directories, 1 file

$ tree -L 1 example-backup
example-backup
├── rdiff-backup-data
└── time.txt

1 directory, 1 file

搭配官網上的這句話,我們可以得知rdiff-backup-data 這個資料夾的目的,就是儲存額外的訊息,例如過去的備份(增量備份),和備份過程的紀錄 等。除了它之外,整個目標資料夾(example-backup)會跟目前來源資料夾(example)完全相同。

…The target directory ends up a copy of the source directory, but extra reverse diffs are stored in a special subdirectory of that target directory…

多執行幾次備份之後,我們就可以試著列出目前的備份:

# 寫入目前時間
date | tee -a example/time.txt
# 用 rdiff-backup 備份
rdiff-backup example example-backup

可以使用 --list-increments 列出目前的備份:

$ rdiff-backup --list-increments example-backup
Found 2 increments:
    increments.2021-09-05T00:49:13+08:00.dir   Sun Sep  5 00:49:13 2021
    increments.2021-09-05T01:42:18+08:00.dir   Sun Sep  5 01:42:18 2021
Current mirror: Sun Sep  5 01:42:30 2021

或者 --list-increment-sizes 以表格的方式列出:

$ rdiff-backup --list-increment-sizes example-backup
        Time                       Size        Cumulative size
-----------------------------------------------------------------------------
Sun Sep  5 01:42:30 2021         4.09 KB           4.09 KB   (current mirror)
Sun Sep  5 01:42:18 2021        68 bytes           4.16 KB
Sun Sep  5 00:49:13 2021        99 bytes           4.26 KB

這邊也可以看出 增量備份 的效果,注意看 Size 的數字,過去的備份佔用的空間相對小了很多。最新一次的備份大約佔了 4.09 KB,而每新增一次的歷史,只佔用數十 bytes。

從一個範例開始(還原)

前面我們進行了幾次備份,現在我們要試著還原過去的版本,首先看一下目前有哪些備份:

$ rdiff-backup --list-increment-sizes example-backup
        Time                       Size        Cumulative size
-----------------------------------------------------------------------------
Sun Sep  5 01:42:30 2021         4.09 KB           4.09 KB   (current mirror)
Sun Sep  5 01:42:18 2021        68 bytes           4.16 KB
Sun Sep  5 00:49:13 2021        99 bytes           4.26 KB

可以用 --restore-as-of 選擇要還原那一個版本(其實也只有這一個選項),官方說明如下:

-r, --restore-as-of restore_time
              Restore  the  specified  directory as it was as of restore_time.
              See the TIME FORMATS section for more information on the  format
              of restore_time, and see the RESTORING section for more informa‐
              tion on restoring.

使用 --restore-as-of 一定要指定時間(restore_time):

rdiff-backup --restore-as-of 'Sun Sep  5 01:42:30 2021' example-backup example-restore

還原出來的文件與來源完全相同:

$ tree -L 1 example-restore
example-restore
└── time.txt

0 directories, 1 file
$ diff example/time.txt example-restore/time.txt

注意:還原時 rdiff-backup 會檢查目標資料夾,如果已經存在的話,會顯示下面的錯誤訊息

$ rdiff-backup --restore-as-of 'Sun Sep  5 01:42:30 2021' example-backup example
Fatal Error: Restore target example already exists, specify --force to overwrite.

另外,若是要還原最新一次的備份,可以直接指定 now

rdiff-backup --restore-as-of now example-backup example-restore

最後,若是要覆蓋現有的資料夾(e.g. 來源資料夾),可以加上 --force 來達成:

rdiff-backup --restore-as-of now --force example-backup example

刪除過去的備份

很多時候,我們會搭配工作排程器,做成自動備份的機制,提供災難復原的能力。但是太多用不到的舊資料,就這麼放著也是浪費空間,幸好 rdiff-backup 也提供備份檔的管理能力。

使用 --remove-older-than 可以刪除過時的備份檔(其實也只有這一個選項),官方說明如下:

--remove-older-than time_spec
              Remove the incremental backup information in the destination di‐
              rectory that  has  been  around  longer  than  the  given  time.
              time_spec  can be either an absolute time, like "2002-01-04", or
              a time interval.  The time interval is an  integer  followed  by
              the  character  s, m, h, D, W, M, or Y, indicating seconds, min‐
              utes, hours, days, weeks, months, or years  respectively,  or  a
              number  of  these  concatenated.  For example, 32m means 32 min‐
              utes, and 3W2D10h7s means 3 weeks, 2 days, 10 hours, and 7  sec‐
              onds.   In  this  context,  a month means 30 days, a year is 365
              days, and a day is always 86400 seconds.

它需要代一個參數 time_spec,它可以是幾個備份、幾小時 或幾天,格式如下:

  • s:秒
  • m:分鐘
  • h:小時
  • D:天
  • W:周
  • M:月(固定 30 天)
  • Y:年(固定 365 天)

先看一下目前的備份:

$ rdiff-backup --list-increment-sizes example-backup
        Time                       Size        Cumulative size
-----------------------------------------------------------------------------
Sun Sep  5 18:02:25 2021         4.16 KB           4.16 KB   (current mirror)
Sun Sep  5 18:02:04 2021        68 bytes           4.22 KB
Sun Sep  5 01:42:30 2021       102 bytes           4.32 KB
Sun Sep  5 01:42:18 2021        68 bytes           4.39 KB
Sun Sep  5 00:49:13 2021        99 bytes           4.49 KB

舉例來說,若是我們要刪除一天前的備份,可以使用 --remove-older-than 1D

$ rdiff-backup --remove-older-than 1D example-backup
Deleting increment at time:
Sun Sep  5 00:49:13 2021

假如我們要刪除 12 小時前的備份呢?因為我們還有兩個備份超過 12 小時,預設情況下 rdiff-backup 一次只會刪除一個備份,所以會出現以下的錯誤訊息:

$ rdiff-backup --remove-older-than 12h example-backup
Fatal Error: Found 2 relevant increments, dated:
Sun Sep  5 01:42:18 2021
Sun Sep  5 01:42:30 2021
If you want to delete multiple increments in this way, use the --force.

如果要一次刪除多個備份,請加上 --force 選項:

$ rdiff-backup --remove-older-than 12h --force example-backup
Deleting increments at times:
Sun Sep  5 01:42:18 2021
Sun Sep  5 01:42:30 2021

另一種時間格式(B

間天提到的兩個指令,其實支援相當多種不同的時間格式,除了 W3C 制定的時戳的格式(大約像是:2021-09-05T01:00:00+08:00)之外,還支援 B 這個單位。它的意思是 backup,也就是備份。舉例來說:0B 就是 now 就是最新一次的備份,1B 是第一個增量(也就是第二個備份),依此類推。

  • --restore-as-of
  • --remove-older-than

一樣拿前面的備份來測試:

$ rdiff-backup --list-increment-sizes example-backup             
        Time                       Size        Cumulative size
-----------------------------------------------------------------------------
Sun Sep  5 18:02:25 2021         4.16 KB           4.16 KB   (current mirror)
Sun Sep  5 18:02:04 2021        68 bytes           4.22 KB
Sun Sep  5 01:42:30 2021       102 bytes           4.32 KB
Sun Sep  5 01:42:18 2021        68 bytes           4.39 KB
Sun Sep  5 00:49:13 2021        99 bytes           4.49 KB

--restore-as-of 來示範的話,以下指令會取出第一個增量備份,也就是第二行的 Sun Sep 5 18:02:04 2021 這個備份:

rdiff-backup --restore-as-of 1B example-backup example2

注意--remove-older-than 的意思是刪除比 XX 還舊的備份,換句話說,當我指定 4B 的時候,沒有任何備份會被刪除,因為它已經是最後一個備份了。

$ rdiff-backup --remove-older-than 4B --force example-backup  
No increments older than Sun Sep  5 00:49:13 2021 found, exiting.

備份至遠端主機

在備份之前,請先在遠端主機上安裝好 rdiff-backup(本例為 192.168.1.46):

# 在備份目的地主機執行
ssh 192.168.1.46
# 在備份目的地主機執行
sudo apt install rdiff-backup

因為是透過 SSH 備份,第一次連線的時候需要先確認公鑰指紋:

$ rdiff-backup example 192.168.1.46::/home/alexleo/example-backup
The authenticity of host '192.168.1.46 (192.168.1.46)' can't be established.
ECDSA key fingerprint is SHA256:OKnlK1OCF+17uUAjdIQQ3gavXE1pQpbotWRQADZvQVI.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added '192.168.1.46' (ECDSA) to the list of known hosts.
[email protected]'s password:

確實有備份成功了:

$ rdiff-backup --list-increment-sizes 192.168.1.46::/home/alexleo/example-backup
[email protected]'s password:
        Time                       Size        Cumulative size
-----------------------------------------------------------------------------
Tue Sep  7 15:50:34 2021         4.16 KB           4.16 KB   (current mirror)

還原也沒問題:

rdiff-backup --restore-as now --force 192.168.1.46::/home/alexleo/example-backup example

從遠端主機備份過來

同理,備份的目標也可以是遠端主機上的檔案!

首先建立範例資料夾與檔案:

ssh 192.168.1.46 "mkdir example"
ssh 192.168.1.46 "date | tee -a example/time.txt"

使用以下指令備份:

rdiff-backup 192.168.1.46::/home/alexleo/example remote-backup

確實有備份成功了:

$ rdiff-backup --list-increment-sizes remote-backup             
        Time                       Size        Cumulative size
-----------------------------------------------------------------------------
Tue Sep  7 16:18:21 2021         4.03 KB           4.03 KB   (current mirror)

還原也沒問題:

rdiff-backup --restore-as-of now --force remote-backup 192.168.1.46::/home/alexleo/example

參考資料:

注:diff-backup 的圖樣屬於該開源專案,本文基於描述需要合理使用。 (Note: Usage of diff-backup banner logo here is for the purpose of describing only.)

發表迴響