rsyncによるハードリンク世代バックアップ
rsyncによるハードリンク世代バックアップ
本記事では,Linux環境でのrsyncを使った**世代バックアップ(世代管理)**の方法について解説します.
特にハードリンクを活用することで,ディスク容量を節約しつつ,各世代をフルバックアップのように扱う方法を説明します.
前提条件
- Linux/Unix環境
- バックアップ元ディレクトリ: /data
- バックアップ先ディレクトリ: /backup
- 世代ディレクトリは日付形式: YYYYMMDD
- ファイルシステム: ext4 (rsync運用で十分)
初回バックアップ
初回バックアップは単純なrsyncコピーで実行します.
#!/bin/bash SRC="/data/" DST="/backup/$(date +%Y%m%d)" # 初回は普通にコピー rsync -a --delete "$SRC" "$DST"
- オプション説明
- -a: アーカイブ(再帰+属性保持)
- –delete: 元にないファイルを削除
- 初回は単純コピーでOKです.
- –delete: 元にないファイルを削除
- -a: アーカイブ(再帰+属性保持)
2回目以降の世代バックアップ(ハードリンク利用)
ハードリンクを利用すると,前回バックアップと同じファイルはリンク化され,ディスク容量を節約できます.
#!/bin/bash SRC="/data/" DST="/backup/$(date +%Y%m%d)" PREV="$(ls -1 /backup | sort | tail -n1)" # 直前世代 rsync -a --delete --link-dest="/backup/$PREV" "$SRC" "$DST"
- –link-dest: 前回世代のディレクトリを指定することで,同一ファイルはハードリンクに
- 新規・更新ファイルのみコピーされ,古い世代は残ります
世代管理(prune)
古い世代を削除してディスク容量を管理する操作をpruneと呼びます.
# 例: 直近7世代だけ残す
(
cd $DST_PHYS
echo "delete older gen, keep gens:$KEEP_GEN"
printf '%s\n' 20* | sort
for d in $(printf '%s\n' 20* | sort | head -n -$KEEP_GEN); do
rm -rI "$d"
done
)
- 古い世代だけを明示的に削除することで,安全にディスク容量を回収できます.
- 注意点: ハードリンクは他の世代で参照されている場合,データ自体は消えません.
ハードリンクの特徴
- 同じinodeを指す複数のファイル名が存在する
- リンクカウントが0になったときに初めてディスク上のデータが解放される
- 世代バックアップでは,個別世代を削除しても他の世代が残っていればデータは消えません
- 全世代まとめて削除(例: rm -rf /backup)するとデータは全て消えます
運用上のベストプラクティス
- バックアップ専用のディレクトリを用意
- 世代削除はまとめてではなく,古い世代だけを明示的に削除
- cronなどで自動化可能
- ディスク容量が大きい場合,ext4で十分
- ログを残すとトラブル時に安心
まとめ
- rsync + –link-dest で見た目はフルバックアップだが,容量効率は差分バックアップ
- 古い世代を削除することでディスク容量を制御できる(prune)
- ハードリンクの性質を理解していれば,安全に世代バックアップを運用可能
注意
インフラ慣れした管理者には言うまでもないですが,rsync はパス最後の / を厳格に判定します.
これは,–link-dest= に対しても同様です.
例えば,
- src: mnt/storage/wd
- dst: mnt/crypt/wd/20260315
の様な環境だとします.
この状態で,上記に示してきた様な –link-dest=20260314 みたいな指定を行うとします.
つまり,
rsync -ax --delete --link-dest=20260314 /mnt/storage/wd/ /mnt/crypt/wd/20260315/
ですね.
実はこれは NG です.この場合,rsync は,リンク判定比較先として,/mnt/crypt/wd/20260315/20260314/ を見に行きます.
結果,そこにはファイルがないので,差分ではなく,全部コピーとなってしまいます.
正解は,
rsync -ax --delete --link-dest=/mnt/crypt/wd/20260314/ /mnt/storage/wd/ /mnt/crypt/wd/20260315/
と,link-dest= もフルパス指定する必要があります.