rsync(差分バックアップ)
『rsync』はローカル・リモート間でファイルを差分同期するコマンドです。変更のあったファイルだけを転送するため、フルコピーより高速で帯域を節約できます。SSH を経由してリモートサーバーへ安全にバックアップしたり、cron と組み合わせて定期的な自動バックアップを構築したりするために広く使われています。
構文
# -----------------------------------------------
# rsync の基本構文
# -----------------------------------------------
# rsync [オプション] 送信元 宛先
# → 送信元から宛先へ差分のみを転送・同期します
# → ローカル間・SSH リモート間どちらにも対応しています
# -----------------------------------------------
# よく使うオプション
# -----------------------------------------------
# -a(--archive)
# → アーカイブモード。-rlptgoD と同等で、
# 再帰コピー・シンボリックリンク保持・パーミッション保持・
# タイムスタンプ保持・オーナー保持をまとめて有効にします
# 例: rsync -a /src/ /dst/
# -v(--verbose)
# → 転送中のファイル名を詳細表示します
# -z(--compress)
# → 転送データを圧縮します。ネットワーク越しのバックアップに有効です
# -n(--dry-run)
# → 実際には転送せず、何が同期されるかを事前確認します
# 例: rsync -avn /src/ user@remote:/dst/
# -e(--rsh)
# → 使用するリモートシェルを指定します
# 例: -e "ssh -p 2222" → SSH ポート 2222 を使用します
# --delete
# → 送信元に存在しないファイルを宛先から削除します(完全ミラーリング)
# 例: rsync -az --delete /src/ user@remote:/dst/
# --exclude={パターン}
# → 指定したパターンに一致するファイルを除外します
# 例: --exclude="*.log"
# --exclude-from={ファイル}
# → 除外パターンの一覧をファイルから読み込みます
# 例: --exclude-from=/home/okabe/exclude_list.txt
# --backup
# → 上書きされる既存ファイルをバックアップとして保存します
# --backup-dir={ディレクトリ}
# → --backup で保存するバックアップの格納先を指定します
# --progress
# → 各ファイルの転送進捗を表示します
# --stats
# → 転送完了後に合計転送量や転送速度などの統計情報を表示します
# --link-dest={ディレクトリ}
# → 前回バックアップと同一ファイルはハードリンクで参照します
# → 変更ファイルだけ実体コピーされるため、世代バックアップに最適です
構文一覧
| オプション | 説明 |
|---|---|
-a(--archive) | アーカイブモード。再帰・パーミッション・タイムスタンプ・オーナー等をまとめて保持します。バックアップの基本オプションです。 |
-v(--verbose) | 転送されるファイル名を詳細表示します。-vv でさらに詳しくなります。 |
-z(--compress) | 転送データをリアルタイムで圧縮します。低速なネットワーク回線のバックアップ時間を短縮できます。 |
-n(--dry-run) | 実際には転送せず、同期される内容を事前確認します。-v と組み合わせると変更一覧が表示されます。 |
-e(--rsh) | 使用するリモートシェルを指定します。SSH のポート変更や鍵ファイルの指定に使います。 |
--delete | 送信元に存在しないファイルを宛先から削除します。完全なミラーリングが必要な場合に指定します。 |
--exclude={パターン} | 指定パターンに一致するファイル・ディレクトリを同期から除外します。ワイルドカードが使えます。 |
--exclude-from={ファイル} | 除外パターン一覧をファイルから読み込みます。除外項目が多い場合に管理しやすくなります。 |
--backup | 宛先で上書きされるファイルを別名で保存します。--backup-dir と組み合わせて使います。 |
--backup-dir={ディレクトリ} | --backup で保存する旧ファイルの格納先ディレクトリを指定します。 |
--progress | 各ファイルの転送進捗(転送量・速度・残り時間)をリアルタイムで表示します。 |
--stats | 転送完了後に合計転送ファイル数・転送量・転送速度などの統計を表示します。 |
--link-dest={ディレクトリ} | 指定ディレクトリと同一ファイルをハードリンクで参照し、変更ファイルのみ実コピーします。世代バックアップのディスク節約に最適です。 |
使用例
リモートサーバーへの差分バックアップ
# -----------------------------------------------
# ローカルから SSH 経由でリモートへ差分バックアップします
# -----------------------------------------------
# 岡部倫太郎のホームディレクトリを
# リモートサーバー(mayuri-backup)の /backup/okabe/ へ同期します。
# --delete により、ローカルで削除したファイルはリモートからも削除されます。
# -n(ドライラン)で事前に何が転送されるか確認してから実行するのが安全です。
# まず --dry-run で差分を確認します
rsync -avzn --delete \
/home/okabe/ \
mayuri@mayuri-backup:/backup/okabe/
# 内容を確認したら -n を外して実際に転送します
rsync -avz --delete \
/home/okabe/ \
mayuri@mayuri-backup:/backup/okabe/
# SSH のポートが 2222 の場合は -e オプションで指定します
rsync -avz --delete \
-e "ssh -p 2222 -i /home/okabe/.ssh/id_ed25519" \
/home/okabe/ \
mayuri@mayuri-backup:/backup/okabe/
実行するコマンドは次の通りです。
$ rsync -avz --delete /home/okabe/ mayuri@mayuri-backup:/backup/okabe/ sending incremental file list ./ .bashrc Documents/steins_gate_notes.txt Documents/divergence_memo.txt Pictures/lab_members.jpg sent 1,234,567 bytes received 4,321 bytes 567,890.00 bytes/sec total size is 9,876,543 speedup is 7.98
--link-dest を使った世代バックアップ
# -----------------------------------------------
# --link-dest による世代バックアップ(差分ハードリンク方式)
# -----------------------------------------------
# 今日の日付のディレクトリへバックアップします。
# --link-dest に前回のバックアップを指定することで、
# 変更のないファイルはハードリンクになり、ディスク消費を大幅に節約できます。
TODAY=$(date +%Y-%m-%d)
YESTERDAY=$(date -d yesterday +%Y-%m-%d)
BACKUP_ROOT=/backup/kurisu
# 前回のバックアップをハードリンク元として今日のバックアップを作成します
rsync -az --delete \
--link-dest="${BACKUP_ROOT}/${YESTERDAY}" \
/home/kurisu/ \
"${BACKUP_ROOT}/${TODAY}/"
実行するコマンドは次の通りです。
$ ls /backup/kurisu/ 2025-03-23 2025-03-24 2025-03-25 $ du -sh /backup/kurisu/2025-03-25 4.2M /backup/kurisu/2025-03-25
除外リストを使ってバックアップ対象を絞る
# -----------------------------------------------
# 除外リストファイルを使った選択的バックアップ
# -----------------------------------------------
# 椎名まゆりの作業ディレクトリを同期しますが、
# キャッシュや一時ファイルはバックアップ対象から除外します。
# 除外リストファイルを作成します(1行1パターン)
cat <<'EOF' > /home/mayuri/rsync_exclude.txt
.cache/
.npm/
node_modules/
*.tmp
*.log
*.swp
EOF
# 除外リストを参照しながらバックアップします
rsync -avz \
--exclude-from=/home/mayuri/rsync_exclude.txt \
/home/mayuri/workspace/ \
hashida@lab-server:/backup/mayuri/workspace/
実行するコマンドは次の通りです。
$ rsync -avz --exclude-from=/home/mayuri/rsync_exclude.txt \ > /home/mayuri/workspace/ hashida@lab-server:/backup/mayuri/workspace/ sending incremental file list project_alpha/main.py project_alpha/config.json project_beta/README.txt sent 87,654 bytes received 1,234 bytes 35,555.20 bytes/sec total size is 4,567,890 speedup is 51.56
crontab でデイリーバックアップを自動化
# -----------------------------------------------
# crontab に登録して毎日自動バックアップを実行します
# -----------------------------------------------
# バックアップスクリプト /usr/local/bin/daily_backup.sh を作成します
#!/bin/bash
TODAY=$(date +%Y-%m-%d)
YESTERDAY=$(date -d yesterday +%Y-%m-%d)
BACKUP_ROOT=/backup/lab-members
LOG=/var/log/rsync_backup.log
REMOTE_USER=rukako
REMOTE_HOST=divergence-storage
REMOTE_PORT=22
# ログに開始時刻を記録します
echo "=== Backup started: $(date) ===" >> "${LOG}"
# /home 以下の全ユーザーをまとめてバックアップします
# --link-dest で前日のバックアップをハードリンク元に指定します
rsync -az --delete \
--link-dest="${BACKUP_ROOT}/${YESTERDAY}" \
-e "ssh -p ${REMOTE_PORT} -i /root/.ssh/id_ed25519" \
/home/ \
"${REMOTE_USER}@${REMOTE_HOST}:${BACKUP_ROOT}/${TODAY}/" \
>> "${LOG}" 2>&1
# 終了ステータスをログに記録します
if [ $? -eq 0 ]; then
echo "Backup succeeded: ${TODAY}" >> "${LOG}"
else
echo "Backup FAILED: ${TODAY}" >> "${LOG}"
fi
# 30日以上前のバックアップディレクトリを削除してディスクを節約します
find "${BACKUP_ROOT}" -maxdepth 1 -type d -mtime +30 -exec rm -rf {} +
echo "=== Backup finished: $(date) ===" >> "${LOG}"
同じ処理を次のようにも書けます。
# ----------------------------------------------- # 作成したスクリプトに実行権限を付与し crontab に登録します # ----------------------------------------------- # スクリプトに実行権限を付与します chmod +x /usr/local/bin/daily_backup.sh # crontab を編集して毎日午前 3 時に実行するよう登録します crontab -e
実行するコマンドは次の通りです。
# 以下の行を crontab に追記します(毎日 03:00 実行) 0 3 * * * /usr/local/bin/daily_backup.sh
概要
『rsync』はデルタ転送アルゴリズムによってファイルの差分だけを転送します。初回は全ファイルをコピーしますが、2回目以降は変更部分のみ転送するため、ネットワーク帯域とバックアップ時間を大幅に削減できます。SSH を経由するリモートバックアップでは ssh_config で接続先を管理しておくと、-e オプションの記述が簡潔になります。--link-dest を活用した世代バックアップは各世代が完全なスナップショットに見えながら、実際には変更ファイルだけ実体コピーされるためストレージ効率が高く、本番サーバーのバックアップ戦略として広く採用されています。定期実行には crontab に登録するのが一般的です。--dry-run(-n)で事前に差分を確認してから本番実行する習慣をつけると、意図しないファイル削除や上書きを防げます。
記事の間違いや著作権の侵害等ございましたらお手数ですがこちらまでご連絡頂ければ幸いです。