rsnapshot 適合在 Linux 備份伺服器上儲存“能直接瀏覽的歷史版本”。它以 rsync 完成同步,並透過硬連結複用未變化的檔案。
因此,daily.0、daily.1、weekly.0 看起來都像完整備份,但相同檔案通常只佔一份資料空間。恢復時也不需要匯入專用資料庫,找到對應快照並複製檔案即可。
本文按四類來源展開:
- Linux 本機目錄;
- 透過 SSH 訪問的遠端 Linux 目錄;
- Windows 或 Samba 共享;
- 透過 SMB/CIFS 或 NFS 提供檔案的 NAS。
示例統一把快照寫入:
|
|
正式操作前,請把示例 IP、使用者名稱、共享名和目錄替換成自己的值。
功能介紹與基本命令
rsnapshot 的資料流
最常見的部署方式是讓一臺 Linux 機器充當備份伺服器:
|
|
備份伺服器負責讀取源資料、寫入快照、執行定時任務和儲存日誌。對於遠端 Linux,rsnapshot 透過 SSH 主動拉取;對於 Windows 或 NAS,共享目錄通常先掛載到 Linux,再按本地目錄備份。
rsnapshot 不是實時同步工具,也不是異地備份策略本身。它能降低誤刪、誤改和需要歷史版本時的恢復成本,但無法替代離線副本、異地副本和恢復演練。
安裝所需軟體
Ubuntu 或 Debian 可以安裝:
|
|
各元件用途如下:
rsnapshot:管理同步和快照輪轉;rsync:複製變化的資料;openssh-client:連線遠端 Linux;cifs-utils:掛載 Windows、Samba 和常見 NAS 的 SMB 共享;nfs-common:掛載 NAS 的 NFS 匯出。
確認命令位置:
|
|
本文示例使用 /usr/bin/rsnapshot、/usr/bin/rsync 和 /usr/bin/ssh。如果系統輸出不同,應以實際路徑為準。
先檢查備份盤
建立快照根目錄:
|
|
快照根目錄應位於支援硬連結的 Linux 檔案系統上,例如 ext4 或 XFS。不要把它直接放到 FAT、exFAT 等不支援 Unix 硬連結的檔案系統中。
如果 /mnt/backup 是獨立硬碟,還要確認它確實已經掛載。否則磁碟掛載失敗後,任務可能把備份寫進系統盤上的同名空目錄。
可先做一次硬連結測試:
|
|
兩個測試檔案的 inode 號應相同。
配置檔案的基本結構
主配置通常是 /etc/rsnapshot.conf:
|
|
配置項和引數之間必須使用 Tab 製表符。程式碼塊顯示寬度可能與編輯器不同,貼上後應檢查實際字元,不能用一串普通空格代替 Tab。
這組保留策略表示:
- 儲存 7 個每日快照;
- 儲存 4 個每週快照;
- 儲存 6 個每月快照。
預設模式下,列表中最頻繁的 daily 執行實際 rsync 同步並輪轉每日快照;weekly 和 monthly 主要把較低層級的舊快照向上輪轉。若啟用了 sync_first 1,行為會改變,不能再照搬本文的定時方式。
常用命令速查
檢查配置語法:
|
|
正常結果應包含:
|
|
預覽命令但不實際備份:
|
|
執行每日同步:
|
|
檢視快照佔用:
|
|
使用自定義配置檔案:
|
|
如果任務由普通使用者 test 執行,則檢查、SSH 金鑰和目錄許可權都必須屬於同一個使用者:
|
|
備份 Linux 目錄
備份本機目錄
假裝置份以下目錄:
|
|
在 /etc/rsnapshot.conf 中新增:
|
|
當全域性 rsync_long_args 包含 --relative 時,來源的目錄層級會保留,結果通常類似:
|
|
先執行:
|
|
仔細檢查 dry-run 輸出中的源路徑和目標路徑,確認不會寫錯位置,再正式執行:
|
|
透過 SSH 備份遠端 Linux
假設環境如下:
|
|
遠端機器通常不必安裝 rsnapshot,但必須執行 SSH 服務,並且遠端環境中要有 rsync。
先在遠端機器確認:
|
|
如果 rsnapshot 由 root 的 cron 執行,就為 root 配置 SSH 金鑰:
|
|
最後一條命令必須能夠直接登入,不能要求輸入密碼或確認 host key。
如果任務由 test 使用者執行:
|
|
配置備份點:
|
|
之後依次驗證:
|
|
如果使用 --relative,快照中可能保留 data/files 這一層。這不是重複備份,而是 rsync 的相對路徑行為。
控制遠端目錄在快照中的層級
如果希望 /data/files/ 內的內容直接出現在 remote-linux/ 下,可用 /./ 標記相對路徑起點:
|
|
備份結果會更接近:
|
|
路徑語義容易被末尾斜槓和 --relative 影響,所以不要只憑預期判斷。應先執行 rsnapshot -t daily,必要時再直接做一次 rsync dry-run。
非標準 SSH 埠
遠端 SSH 埠為 2222 時,可在全域性配置中寫:
|
|
先手動測試:
|
|
如果只有一臺伺服器使用特殊埠,建議改用 ~/.ssh/config,避免全域性 ssh_args 影響其他備份點:
|
|
對應配置為:
|
|
備份多臺 Linux 主機
每個來源使用獨立目標名稱:
|
|
這樣恢復時可以立即看出資料來自哪臺機器,也能避免不同來源寫入同一目錄。
只備份根目錄下的 .git 裸倉庫
假設 NAS 上的目錄為:
|
|
只保留根目錄下以 .git 結尾的目錄及其全部內容:
|
|
前三處分隔使用 Tab,第四列中的 rsync 引數使用普通空格。+rsync_long_args= 表示追加到全域性引數,而不是整體替換。
過濾規則順序不能顛倒。rsync 按第一條匹配規則決定是否包含物件,所以 --include=/*.git/*** 必須位於 --exclude=* 前面。
先直接測試 rsync:
|
|
輸出中應出現 .git 目錄及其內容,不應出現 website/、test/ 或 README.txt。
如果規則後來由“備份全部”改成“只備份 .git”,舊快照裡的其他內容不會因此從歷史快照消失。若要讓新的 daily.0 清理已排除物件,需要理解並測試 --delete-excluded 的影響;它可能刪除目標中不再匹配過濾規則的資料,不能在未經 dry-run 驗證時直接啟用。
備份遠端 Windows 共享、NAS 和 Samba 目錄
選擇 SMB、NFS 還是 SSH
可按來源能力選擇:
- Windows 檔案共享:通常使用 SMB/CIFS;
- Samba 伺服器:通常使用 SMB/CIFS,也可以直接透過 SSH + rsync;
- 群暉、威聯通等 NAS:可使用 SMB/CIFS、NFS,或在可控環境中使用 SSH + rsync;
- 遠端 Windows 已配置 OpenSSH 和 WSL rsync:可以透過 SSH 拉取,但部署和路徑處理更復雜。
對於普通 Windows 共享,最容易維護的方式是先在 Linux 上只讀掛載,再讓 rsnapshot 備份掛載點。
建立 SMB 憑據檔案
不要把密碼直接寫在 /etc/fstab 或命令歷史中。建立 root 可讀的憑據檔案:
|
|
內容為:
|
|
如果不使用域,可刪除 domain 行。再確認許可權:
|
|
預期許可權是 600 root:root。
手動掛載 Windows 或 Samba 共享
假設共享地址為 //192.168.8.100/files:
|
|
驗證掛載和讀取:
|
|
先確認共享能穩定讀取,再寫入 rsnapshot 配置。若手動掛載都失敗,rsnapshot 不會解決認證、協議或網路問題。
配置開機自動掛載
在 /etc/fstab 中加入一行:
|
|
測試時不要直接重啟:
|
|
其中:
ro:以只讀方式掛載,降低備份機誤改源資料的風險;credentials=:從獨立檔案讀取賬號密碼;vers=3.0:明確嘗試 SMB 3.0;_netdev:標記這是依賴網路的掛載;nofail:掛載失敗時不阻止系統繼續啟動。
nofail 隻影響啟動行為,不代表備份任務應忽略掛載失敗。定時備份前仍然必須檢查掛載狀態。
把 SMB 掛載點加入 rsnapshot
配置:
|
|
然後驗證:
|
|
不要只檢查目錄是否存在。即使 SMB 掛載已經掉線,本地掛載點目錄仍可能存在,但裡面是空的。
掛載 NAS 的 NFS 匯出
假設 NAS 匯出 192.168.8.200:/volume1/files:
|
|
對應 /etc/fstab 示例:
|
|
rsnapshot 配置:
|
|
NFS 的使用者對映和許可權模型與 SMB 不同。能掛載不等於能讀取全部檔案,應使用實際執行 rsnapshot 的賬戶遞迴抽查目錄。
防止共享掉線後生成空快照
最簡單的 cron 防護是先檢查所有必要掛載點:
|
|
如果任意掛載點不存在,rsnapshot 不會執行。
還可以再檢查一個只存在於共享中的哨兵檔案:
|
|
哨兵檔案能夠發現“掛載點存在但掛載的是錯誤共享”等問題。檔案應由源端管理員建立,並保證備份賬戶可讀。
定時備份與快照輪轉
推薦的 cron 順序
假設配置為:
|
|
可編輯 root 的 crontab:
|
|
寫入:
|
|
真正寫入 crontab 時,星號前不要新增反斜槓。
高階別輪轉安排在每日同步之前,是為了讓 monthly、weekly 先接收即將從較低層級淘汰的快照。每月 1 日恰好也是星期日時,執行順序為 monthly、weekly、daily。
給多個層級加同一個鎖
磁碟慢、檔案多或網路不穩定時,一次 daily 可能執行到 weekly 的計劃時間。可用 flock 防止重疊:
|
|
-n 表示拿不到鎖就立即退出。這樣不會同時啟動兩個 rsnapshot,但要結合日誌監控,避免任務長期因鎖衝突而被跳過。
如果 daily 前必須檢查 SMB 和 NFS 掛載,建議寫一個 root 擁有、不可被普通使用者修改的包裝指令碼,再由 cron 呼叫。不要在 crontab 裡堆疊過長的複合命令。
首次啟用定時任務前的驗收
依次完成:
|
|
還要確認 cron 使用的 root 能免互動連線每一臺遠端 Linux:
|
|
命令應直接返回成功,不應等待密碼或首次連線確認。
驗證硬連結確實生效
連續生成兩個快照後,選擇一個未變化檔案:
|
|
若 inode 相同且硬連結計數大於 1,說明兩個快照共享同一份檔案資料。
不要用 du -sh daily.0 daily.1 簡單相加來估算真實新增空間。硬連結會讓逐目錄統計看起來像每個快照都佔一份完整容量。
恢復檔案
恢復前先瀏覽歷史快照:
|
|
將檔案恢復到臨時目錄:
|
|
先檢查恢復檔案,再決定是否覆蓋生產目錄。恢復到遠端伺服器時,建議先 rsync 到臨時位置,並由業務負責人確認許可權、所有者和內容。
常見問題與錯誤處理
configtest 報錯或提示欄位數量不對
最常見原因是 Tab 被替換為空格。顯示不可見字元:
|
|
Tab 通常顯示為 \t。修正後重新執行:
|
|
還要檢查命令路徑是否真實存在,以及 snapshot_root 是否可讀寫。
Permission denied (publickey)
這表示執行任務的本地賬戶無法透過 SSH 金鑰登入。用同一賬戶測試:
|
|
檢查以下專案:
- 公鑰是否加入遠端賬戶的
~/.ssh/authorized_keys; - 本地私鑰是否屬於執行 rsnapshot 的賬戶;
- 遠端
.ssh和authorized_keys許可權是否過寬; - cron 是否實際以 root 而不是
test執行; - host key 是否已經由同一賬戶確認。
SSH 能登入,但 rsync 報 command not found
確認遠端路徑:
|
|
如果 rsync 位於非標準位置,可為對應備份點追加:
|
|
不要猜路徑,先在遠端機器實際確認。
遠端目錄沒有讀取許可權
先以遠端備份賬戶測試:
|
|
再繞過 rsnapshot 直接測試 rsync:
|
|
如果仍然出現 Permission denied,問題在遠端賬戶的目錄遍歷或檔案讀取許可權,而不是 rsnapshot。可在遠端檢查:
|
|
優先透過專用只讀賬戶、組許可權或 ACL 授權。不要為了省事把整個源目錄改成所有人可讀寫。
SMB 掛載提示 Permission denied
先檢視核心日誌和掛載錯誤:
|
|
檢查共享名、使用者名稱、域、憑據檔案許可權以及 NAS 是否允許該賬戶訪問。只有在服務端確實較舊時才嘗試其他 vers=,不要把降級到舊協議當成預設解決辦法。
rsnapshot 成功,但 Windows 或 NAS 快照是空的
立即檢查源掛載:
|
|
如果共享未掛載,應停止後續輪轉,先恢復掛載,再執行 daily。不要在空掛載點上連續執行,否則多個新快照都會反映空源狀態。
rsnapshot -t 看起來正確,正式執行仍失敗
-t 主要展示將執行的命令,不會完整驗證傳輸期間的許可權、容量、網路穩定性和所有檔名。應把 dry-run 視為第一道檢查,而不是成功保證。
檢視日誌:
|
|
再複製日誌中的 rsync 命令單獨執行,以確認是網路、許可權、檔名還是磁碟問題。
磁碟空間異常增長
先區分“檔案變動多”和“硬連結失效”:
|
|
大量小檔案會先耗盡 inode;資料庫檔案、虛擬機器映象和持續變化的大檔案即使只改了一小部分,也可能在新快照中佔用新的完整檔案空間。
如果快照根目錄被遷移到不支援硬連結的檔案系統,或不同快照跨檔案系統,空間複用也會失效。重新檢查:
|
|
cron 沒有執行
確認 crontab 內容:
|
|
cron 環境變數比互動式 shell 少,所以任務中應使用絕對命令路徑。不要依賴 shell 中臨時設定的 PATH、SSH agent 或手工掛載狀態。
如果命令手動能執行、cron 不能執行,優先比較兩者的執行賬戶、HOME、SSH 金鑰、known_hosts 和掛載可見性。
任務互相重疊或長期不結束
檢查程序:
|
|
不要在不知道程序階段時直接刪除鎖檔案。先看日誌和程序狀態,確認沒有活躍 rsnapshot 後,再處理遺留鎖。
如果經常跨越計劃視窗,應調整執行時間、減少掃描範圍、修復慢網路,或使用統一的 flock 鎖,而不是允許多個任務併發讀寫同一快照根目錄。
刪除原始檔後,為什麼歷史快照裡還有
這是預期行為。新的 daily.0 可以反映源端刪除,但舊的 daily.1、weekly.0 本來就是歷史版本,直到超出保留數量才會被輪轉刪除。
不要手動進入舊快照逐個刪除檔案來“同步狀態”。這會破壞歷史保留的意義,也可能誤刪仍透過硬連結共享的資料入口。
如何確認備份真的可恢復
至少每月抽樣完成一次恢復:
- 從 daily、weekly 或 monthly 中選擇一個快照;
- 把若干不同型別檔案複製到獨立臨時目錄;
- 核對檔案大小、校驗和和可開啟性;
- 對 Git 裸倉庫執行一致性檢查;
- 記錄恢復時間和發現的問題。
Git 裸倉庫可抽查:
|
|
只有定時任務成功日誌還不夠。真正的驗收標準是能從指定歷史點恢復出正確、可用的資料。
一份可落地的組合配置
下面示例同時備份本機、遠端 Linux、Git 裸倉庫、Windows 共享和 NAS NFS。請確認程式碼塊中的列為 Tab:
|
|
上線順序應固定為:
|
|
逐項確認:
- 快照根目錄位於正確的備份盤;
- SMB 和 NFS 共享真實掛載且可讀;
- SSH 連線不需要互動;
- dry-run 沒有意外來源或目標;
.git過濾結果只包含預期目錄;daily.0中能找到所有關鍵檔案;- 第二次快照的未變化檔案使用硬連結;
- 恢復測試能夠成功開啟檔案。
最後再啟用 cron。這樣出現問題時,可以明確區分配置語法、SSH、共享掛載、源許可權、磁碟容量和定時環境,而不會把所有錯誤都歸到 rsnapshot。