rsyncだけで実現する!ファイルのバックアップ手法6選 【コマンド例編】 – Hacker's High
https://hackers-high.com/linux/rsync-backup-part2/
の内容をもとに実際に試験
よく使われるオプション
オプション 説明
-a アーカイブモード。なるべく転送元ディレクトリの内容を維持したままコピーする。(具体的には、ディレクトリ・シンボリックリンク・パーミッション・タイムスタンプ・所有者・グループ・特殊ファイルをそのまま保持する)
-v 実際に転送されたファイルのリストや、転送量などの統計情報を表示する
-h 表示される情報に適切な単位をつける
-n 実際にファイル転送を行わない。-v と組み合わせると、指定したコマンドでどのようにファイル転送が行われるかの統計情報のみを表示する。コマンドのテストに便利。
-z ファイルを圧縮して転送する。ネットワーク越しの転送に便利。
src
読み方:ソース
Sourceの略。画像のあるurlを指定する属性。
dst
「destination(デスティネーション)」の略語です。 意味は「目的地、行先、あて先」などになります。 dstはsrcと共によく使われる単語です。
$ tree /test/src
/test/src
├── test1
├── test2
└── test3
転送元パスの指定方法
転送元パスがディレクトリの場合、最後に /(スラッシュ)を付けるか付けないかで挙動が変わります。
スラッシュを付けない場合、パスに指定されたディレクトリごとコピーします。
$ rsync -a /test/src /test/dst
$ tree /test/dst
/test/dst
└── src
├── test1
├── test2
└── test3
1 directory, 3 files
スラッシュを付けた場合、パスに指定されたディレクトリ配下のファイルやディレクトリをコピーします。
$ rsync -a /test/src/ /test/dst
[ntaka@localhost test]$ tree /test/dst
/test/dst
├── test1
├── test2
└── test3
0 directories, 3 files
フルバックアップ+増分バックアップ(世代管理なし)
$ rsync -avh /test/src/ /test/dst
1回目のバックアップは、転送元に存在するファイル・ディレクトリをすべて転送先へバックアップします。(=フルバックアップ)
2回目以降のバックアップは、前回のバックアップからの変更部分(変更のあったファイルと新規作成されたファイル)のみ転送されます。(=増分バックアップ)
最もお手軽なバックアップ方法ですが、バックアップデータが同じディレクトリにたまっていくこと、転送元で削除されたファイルがいつまでも転送先に残り続けることから、バックアップディレクトリが多少ごちゃつきます。また、世代管理はできないので、増分バックアップで世代管理をしたい場合は、増分バックアップ(世代管理あり)がおすすめ
ミラーリング (コピー元とコピー先のデータ同期)
$ rsync -avh --delete /test/src/ /test/dst
–delete オプションを付けることで、転送元にないファイルは転送先からも削除されます。
これにより、転送先は常にバックアップ時点での転送元の状態を反映するようになります。(=ミラーリング)もちろん、前回のバックアップから変更がないファイルは転送されません。
バックアップの世代管理をする必要がない場合はこの手法が最も適している
逆増分バックアップ
latest レイティスト 最新情報
dst ディレクトリは最初から存在しないと failed: No such file or directory でエラーになります
初回バックアップ 2回目以降も同じコマンドでOK
$ rsync -avh --delete --backup --backup-dir="../backup-$(date +%Y%m%d-%H%M%S)" /test/src/ /test/dst/backup-latest
sending incremental file list
created directory /test/dst/backup-latest
./
test1
test2
test3
sent 261 bytes received 122 bytes 766.00 bytes/sec
total size is 18 speedup is 0.05
–delete オプションに加えて –backup オプションを付けることで、–delete によって削除されるファイルをバックアップディレクトリに退避します。ミラーリング+ミラーリングで消えるファイルのバックアップ と考えるとわかりやすいかと思います。
バックアップディレクトリの名前は、–backup-dir で指定することができます。コマンド例では、バックアップ時刻のタイムスタンプをディレクトリ名にするように設定しています。
バックアップディレクトリを転送先ディレクトリよりも1つ上の階層「"../backup-$(date +%Y%m%d-%H%M%S)"」に置いているのがミソです。(同じ階層に置くと面倒なことになります。なぜ面倒になるのかは実際に試してみるのがわかりやすいと思います。)
具体的には、以下のような感じでバックアップデータがたまっていきます。
$ tree /test/dst
/test/dst
├── backup-20230111-164146
│ └── test2 (2023年1月11日 16時41分46秒 にミラーリングによって削除されたデータ)
├── backup-20230111-164926
│ └── test3 (2023年1月11日 16時49分26秒 にミラーリングによって削除されたデータ)
└── backup-latest
├── test1
└── test4
差分バックアップ
#初回のバックアップ(フルバックアップ)
$ rsync -avh /test/src/ /test/dst/backup-base
sending incremental file list
created directory /test/dst/backup-base
./
test1
test2
test3
test4
test5
sent 426 bytes received 158 bytes 1.17K bytes/sec
total size is 46 speedup is 0.08
#2回目以降のバックアップ(差分バックアップ)
test2を削除して実行
$ rsync -avh --compare-dest=../backup-base /test/src/ "/test/dst/backup-$(date +%Y%m%d-%H%M%S)"
sending incremental file list
created directory /test/dst/backup-20230112-085329
./
sent 148 bytes received 74 bytes 444.00 bytes/sec
total size is 39 speedup is 0.18
–compare-dest オプションで、既存のバックアップのあるディレクトリを指定すると、そのディレクトリと転送元の差分をバックアップ(増えた分 更新ファイルも)することができます。
コマンド例では、転送先ディレクトリの名前をバックアップ時刻のタイムスタンプにしています。これにより、差分バックアップで世代管理ができます。
増分しかわからない
$ tree /test/dst/backup-20230112-085329
/test/dst/backup-20230112-085329
0 directories, 0 files
削除したtest2 ファイルを新規に作成して実行
$ rsync -avh --compare-dest=../backup-base /test/src/ "/test/dst/backup-$(date +%Y%m%d-%H%M%S)"
sending incremental file list
created directory /test/dst/backup-20230112-091034
./
test2
sent 226 bytes received 94 bytes 640.00 bytes/sec
total size is 58 speedup is 0.18
test3を編集して実行
$ rsync -avh --compare-dest=../backup-base /test/src/ "/test/dst/backup-$(date +%Y%m%d-%H%M%S)"
sending incremental file list
created directory /test/dst/backup-20230112-091756
./
test2
test3
sent 283 bytes received 114 bytes 794.00 bytes/sec
total size is 65 speedup is 0.16
backup-baseとの比較になるので 2回目のバックアップ内容のtest2もバックアップされる
以下のような感じでバックアップデータがたまっていきます。
$ tree /test/dst
/test/dst
├── backup-20230112-085329
├── backup-20230112-091034
│ └── test2
├── backup-20230112-091756
│ ├── test2
│ └── test3
└── backup-base
├── test1
├── test2
├── test3
├── test4
└── test5
4 directories, 8 files
#初回のバックアップ(フルバックアップ)
$ rsync -avh /test/src/ /test/dst/backup-base
sending incremental file list
created directory /test/dst/backup-base
./
test1
test2
test3
test4
test5
sent 443 bytes received 158 bytes 1.20K bytes/sec
total size is 65 speedup is 0.11
test2を削除して実行
2回目バックアップ(差分バックアップ)
$ rsync -avh --link-dest=../backup-base /test/src/ "/test/dst/backup-$(date +%Y%m%d-%H%M%S)"
sending incremental file list
created directory /test/dst/backup-20230112-151057
./
sent 147 bytes received 74 bytes 442.00 bytes/sec
total size is 46 speedup is 0.21
–compare-dest の代わりに –link-dest を使うと、2回目以降のバックアップディレクトリには、–link-dest で指定されたディレクトリと転送元の差分がコピーされるほか、–link-dest で指定されたディレクトリ内の変更がなかったファイルへのハードリンクが張られます。
つまり、見た目上は毎回フルバックアップをとっているように見えます。ただし、既存のファイルはハードリンクを張るだけなので、ファイル転送やディスク消費が発生するのは差分のファイルのみになります。
任意の時点のバックアップをすぐにリストアすることができるという点で、優れたバックアップ方法ですが、増分バックアップ(世代管理あり)がこれのほぼ上位互換なので、どうしても差分バックアップしたい場合くらいしか利用シーンが思いつきません。
削除したtest2 ファイルを新規に作成して実行
$ rsync -avh --link-dest=../backup-base /test/src/ "/test/dst/backup-$(date +%Y%m%d-%H%M%S)"
sending incremental file list
created directory /test/dst/backup-20230112-152719
./
test2
sent 214 bytes received 94 bytes 616.00 bytes/sec
total size is 51 speedup is 0.17
test3を編集して実行
$ rsync -avh --link-dest=../backup-base /test/src/ "/test/dst/backup-$(date +%Y%m%d-%H%M%S)"
sending incremental file list
created directory /test/dst/backup-20230112-153215
./
test2
test3
sent 275 bytes received 114 bytes 778.00 bytes/sec
total size is 56 speedup is 0.14
$ tree /test/dst/
/test/dst/
├── backup-20230112-151057
│ ├── test1
│ ├── test3
│ ├── test4
│ └── test5
├── backup-20230112-152719
│ ├── test1
│ ├── test2
│ ├── test3
│ ├── test4
│ └── test5
├── backup-20230112-153215
│ ├── test1
│ ├── test2
│ ├── test3
│ ├── test4
│ └── test5
└── backup-base
├── test1
├── test2
├── test3
├── test4
└── test5
4 directories, 19 files
増分バックアップ(世代管理あり)
差分バックアップ(ハードリンク)の応用です。
–link-dest が常に1つ前のバックアップを指すようにスクリプトを組んでやると、世代管理ありの増分バックアップを実装できます。
世代管理をするならこのバックアップ手法がいちばん汎用性がある。
#! /bin/bash
BASEDIR="/test/dst" #バックアップ先の親ディレクトリ
LATESTBKUP=$(ls $BASEDIR | grep backup- | tail -n 1) #直近のバックアップのディレクトリ名
rsync -avh --link-dest="$BASEDIR/$LATESTBKUP" /test/src/ "/test/dst/backup-$(date +%Y%m%d-%H%M%S)"
echo "LATESTBKUP="${LATESTBKUP}
exit 0
スクリプトtest.shにして1回目実行
$ ./test.sh
sending incremental file list
created directory /test/dst/backup-20230116-130110
./
test1
test2
test3
test4
test5
test6
sent 488 bytes received 188 bytes 1.35K bytes/sec
total size is 49 speedup is 0.07
LATESTBKUP=
test2ファイルを削除して実行
$ ./test.sh
sending incremental file list
created directory /test/dst/backup-20230116-130643
./
sent 164 bytes received 74 bytes 476.00 bytes/sec
total size is 44 speedup is 0.18
LATESTBKUP=backup-20230116-130110
削除したtest2 ファイルを新規に作成して実行
$ ./test.sh
sending incremental file list
created directory /test/dst/backup-20230116-131039
./
test2
sent 235 bytes received 93 bytes 656.00 bytes/sec
total size is 57 speedup is 0.17
LATESTBKUP=backup-20230116-130643
test3を編集して実行
$ ./test.sh
sending incremental file list
created directory /test/dst/backup-20230116-131324
test3
sent 230 bytes received 91 bytes 642.00 bytes/sec
total size is 62 speedup is 0.19
LATESTBKUP=backup-20230116-131039
$ tree /test/dst/
/test/dst/
├── backup-20230116-130110
│ ├── test1
│ ├── test2
│ ├── test3
│ ├── test4
│ ├── test5
│ └── test6
├── backup-20230116-130643
│ ├── test1
│ ├── test3
│ ├── test4
│ ├── test5
│ └── test6
├── backup-20230116-131039
│ ├── test1
│ ├── test2
│ ├── test3
│ ├── test4
│ ├── test5
│ └── test6
└── backup-20230116-131324
├── test1
├── test2
├── test3
├── test4
├── test5
└── test6
4 directories, 23 files