rsync を用いたバックアップ
この記事では、ファイルやディレクトリの同期・バックアップに使われるコマンドラインツール rsync について解説します。rsync は差分転送により、変更があった部分のみを転送します。ここでは、SSH を利用したリモートサーバーへのバックアップ方法を扱います。
事前準備
rsync で SSH 経由のバックアップを行うには、次の情報を準備します。
- バックアップ先マシンの IP アドレスまたはホスト名(例:
192.168.1.100,backup.example.com) - バックアップ先マシンのログインユーザ名。バックアップ先ディレクトリへの書き込み権限を持つユーザーを使います。
- バックアップ先マシンのバックアップ用ディレクトリ(例:
/var/backups/mydata,~/backups)
SSH 公開鍵認証 を設定しておくと、パスワード入力が不要になり、スクリプトによる自動実行ができます。設定は次のように行います。
# 鍵を作成する(既に鍵がある場合は不要)
ssh-keygen -t ed25519
# 公開鍵をバックアップ先マシンに登録する
ssh-copy-id <ユーザ名>@<IPアドレス>
基本的なリモートバックアップ手順
次のコマンドは、ローカルディレクトリの内容を SSH 経由でリモートマシンのディレクトリに同期します。
sudo rsync -avz --delete -e ssh <バックアップしたいディレクトリ>/ <ユーザ名>@<IPアドレス>:<バックアップ用のディレクトリ>
コマンドの説明:
sudo: スーパーユーザー権限で実行します。バックアップ対象に読み取り権限のないファイルが含まれる場合に必要です。実行ユーザーが対象ディレクトリを読める場合は不要です。rsync: ファイル同期・バックアップを行うコマンドです。- -a (archive): パーミッション、所有者、タイムスタンプなどの属性を保持して再帰的にコピーします(
-rlptgoDと同等)。 - -v (verbose): 処理中のファイル名などを表示します。
- -z (compress): 転送中にデータを圧縮します。ネットワーク帯域を節約できます。高速なネットワークでは CPU 負荷により転送が遅くなる場合があるため、その場合は外します。
- --delete: 転送元に存在しないファイルを転送先から削除し、転送元と転送先を同じ状態(ミラーリング)にします。転送先の既存ファイルが削除されるため、後述の
--dry-runで結果を確認してから実行します。 - -e ssh: 転送に SSH を使用します。通信は暗号化されます。rsync 2.6.0 以降は SSH が既定の転送方式のため、このオプションは省略できます。ポート番号や鍵ファイルを指定する場合は
-e "ssh -p 2222 -i ~/.ssh/id_ed25519"のように書きます。 - -n または --dry-run: 実際の転送を行わず、転送・削除されるファイルを表示します。
<バックアップしたいディレクトリ>/: ローカルマシンのバックアップ対象ディレクトリ(例:/home/user/data/,./project/)<ユーザ名>: リモートマシンへのログインユーザ名<IPアドレス>: リモートマシンの IP アドレスまたはホスト名<バックアップ用のディレクトリ>: リモートマシンのバックアップ先ディレクトリ
< > で囲まれた部分は、実際の値に置き換えて実行してください。
転送元パスの末尾のスラッシュ(/)
- 末尾に
/を付けると、そのディレクトリの中身が転送先ディレクトリの直下にコピーされます。 - 末尾に
/を付けないと、そのディレクトリ自体が転送先ディレクトリ内に作られ、その中に中身がコピーされます。
事前確認(--dry-run)の実行例: 上のコマンドに -n を追加して実行し、転送・削除の対象を確認します。
sudo rsync -avzn --delete -e ssh <バックアップしたいディレクトリ>/ <ユーザ名>@<IPアドレス>:<バックアップ用のディレクトリ>
更新日時が新しいファイルのみバックアップする手順
find コマンドと組み合わせると、条件に一致するファイルのみを転送できます。次の例は、/home の中で過去30日以内に更新されたファイルのみを、ローカルの /backup にコピーします。
cd /home && find . -mtime -30 -type f -print0 | rsync -avz --files-from=- --from0 /home /backup
コマンドの説明:
cd /home: カレントディレクトリを/homeに移動します。&&: 左のコマンド(cd)が成功した場合のみ、右のコマンドを実行します。find . -mtime -30 -type f -print0: カレントディレクトリ(.)以下から、最終更新日時(mtime)が30日以内(-30)のファイル(-type f)を探し、その一覧をヌル文字区切り(-print0)で標準出力に書き出します。ヌル文字区切りは、ファイル名に空白や改行が含まれる場合でも正しく扱えます。|: パイプ。findの標準出力をrsyncの標準入力に渡します。- --files-from=-: 標準入力から読み込んだ一覧のファイルだけを転送対象にします。
- --from0: 読み込む一覧がヌル文字区切りであることを指定します(
findの-print0に対応)。 /home: 転送元の基準パス。findが./...の形で出力した相対パスは、この基準パスからの相対パスとして扱われます。/backup: 転送先ディレクトリ。リモートに送る場合は<ユーザ名>@<IPアドレス>:<バックアップ用のディレクトリ>の形式で指定します。
この手順では --delete を使いません。--files-from で渡すのは更新の新しいファイルのみであり、--delete を併用すると、更新のない古いファイルが転送先から削除されます。転送先には過去の転送結果が蓄積される形になります。
このコマンドも、-n を追加して転送対象を確認してから実行します。
cd /home && find . -mtime -30 -type f -print0 | rsync -avzn --files-from=- --from0 /home /backup