増分&差分に強い自動バックアップ|rsyncオプションとcron実例

バックアップ・復元

「毎日バックアップしたいけど、全部コピーは時間がかかる…」「消してはいけないファイルを安全に同期したい」——そんな悩みを rsync+cron で解決します。rsyncは“変更分(差分/増分)だけ”を転送でき、履歴スナップショットも作れます。この記事では コピペで動く実用例 を中心に、失敗しない設定をまとめました。

まずは最短レシピ(コピペ可)

日次スナップショット(履歴が残る・差分高速)

#!/usr/bin/env bash
set -euo pipefail

SRC="/data"                         # バックアップ元(末尾スラッシュ注意)
ROOT="/backup/snapshots"            # バックアップ保存先(ローカル/外付け/NAS)
STAMP="$(date +%F)"                 # 例: 2025-08-23
TARGET="${ROOT}/${STAMP}"           # 当日のスナップショット
PREV="${ROOT}/latest"               # 直近スナップショットへの参照

mkdir -p "$ROOT"
# 直近との差分のみ転送し、変更のないファイルはハードリンクで高速化
rsync -aHAX --delete \
  --link-dest="$PREV" \
  --info=stats2,progress2 \
  "$SRC/" "$TARGET"

# 最新を張り替え
ln -sfn "$TARGET" "$PREV"

ポイント

  • "$SRC/" の末尾スラッシュは中身をコピーの意味(大事)。
  • --link-dest で未変更ファイルをハードリンクとして再利用 → 履歴を残しつつ容量節約。
  • -aHAX は属性・ハードリンク・ACL・拡張属性を極力保持(環境により未対応のことあり)。

cron で毎日 02:15 に実行

crontab -e
# ↓ 追記(ログと排他もセットに)
MAILTO=""
SHELL=/bin/bash
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/bin

15 2 * * * flock -n /tmp/rsync_daily.lock bash /usr/local/sbin/rsync_daily.sh >>/var/log/rsync_daily.log 2>&1

rsync のキホン(“増分&差分”が速い理由)

  • 差分コピー:サイズやタイムスタンプを見て変更されたファイルだけを転送。
  • デルタ転送:ネットワーク越しではファイルの変更ブロックのみ送るため更に効率的。
  • スナップショット--link-dest を使えば、未変更ファイルは過去のスナップショットをハードリンク参照=履歴が丸ごと残るのに容量は最小限

よく使うオプション早見表

オプション役割 / 効果使いどころ
-aアーカイブ(権限/時刻/再帰など一式)まずはこれ
-Hハードリンク保持同一ファイル群の整合を維持
-A -XACL / 拡張属性保持権限厳密に扱うサーバー等
--delete宛先から削除されたファイルを消すミラー(完全同期)に必須
--link-dest=DIR変更なしは DIR を参照(ハードリンク)スナップショット運用
--exclude, --exclude-from除外パターンキャッシュ・巨大ファイル除外
-z圧縮(転送時)低速回線のリモート転送
-P進捗+中断再開に強い大容量ファイル
--partial-dir=.rsync-partial中断時の一時保存先再開を高速化
--numeric-idsUID/GID を数字として扱う異なるユーザー名環境間
--bwlimit=5m転送帯域制限回線逼迫を回避
--info=stats2,progress2統計と進捗ログで可視化

macOS の標準 rsync は古めです。--info=... など使えない場合は Homebrew 等で rsync 3.x を導入すると便利。

除外設定の実例(除外ファイルで管理)

.rsync-exclude を作っておくと運用が楽です。

# .rsync-exclude
*.tmp
.cache/
node_modules/
.DS_Store
*.iso

適用例:

rsync -a --delete --exclude-from="/etc/rsync/.rsync-exclude" "$SRC/" "$TARGET"

ローカル → 外付けHDD/NAS(履歴スナップショット)

SRC="/data"
ROOT="/Volumes/BackupDisk/snapshots"   # 例: 外付けHDD
STAMP="$(date +%F)"
TARGET="${ROOT}/${STAMP}"
PREV="${ROOT}/latest"

mkdir -p "$ROOT"
rsync -aHAX --delete --link-dest="$PREV" \
  --exclude-from="/etc/rsync/.rsync-exclude" \
  "$SRC/" "$TARGET"
ln -sfn "$TARGET" "$PREV"

古い履歴を30日でローテーション

find "$ROOT" -maxdepth 1 -type d -name "20??-??-??" -mtime +30 -exec rm -rf {} +

安全策:最初は -exec echo rm -rf {} + にして“削除コマンド表示だけ”で検証。

リモートへ SSH バックアップ(オフサイトにも)

鍵認証を設定したうえで、SSH 経由で rsync:

SRC="/data"
HOST="backup1.example.com"
DEST="/srv/backup/hostA"
STAMP="$(date +%F)"
TARGET="${DEST}/${STAMP}"
PREV="${DEST}/latest"

rsync -aHAX --delete \
  --link-dest="$PREV" \
  -e 'ssh -p 22 -i ~/.ssh/id_ed25519 -o StrictHostKeyChecking=accept-new' \
  "$SRC/" "${HOST}:${TARGET}"

ssh -p 22 -i ~/.ssh/id_ed25519 "$HOST" ln -sfn "$TARGET" "$PREV"

コツ

  • 低速回線なら -z --bwlimit=5m
  • 初回は --delete を付けずに ドライランで確認(下記参照)。
  • 異なるユーザー/グループ体系なら --numeric-ids で整合性を確保。

失敗しないための“儀式”(ドライラン & スラッシュ)

ドライラン(実行せず差分だけ確認)

rsync -aHAX --delete --link-dest="$PREV" --dry-run --itemize-changes "$SRC/" "$TARGET"
  • --itemize-changes で何がどう変わるか一覧化。OKなら --dry-run を外して本番実行。

末尾スラッシュの意味

  • SRC/中身をコピー(推奨)
  • SRC:ディレクトリそのものを作成してコピー
    誤解しやすいので、基本は "$SRC/" を固定運用に。

ログ・通知・排他(運用の安定化)

  • 排他flock -n /tmp/rsync_daily.lock で多重起動防止
  • ログ--log-file=/var/log/rsync_daily.log か 1行で >>/var/log/... 2>&1
  • 通知:cron の MAILTO=you@example.com、もしくはエラー時 logger で syslog に投げる
# 例: rsyncの終了コードで通知
rsync -a ... || logger -p user.err "rsync daily backup failed"

パフォーマンス・整合性チューニング

  • ローカル大容量--whole-file(または -W)で差分計算を省略し高速化
  • 途中再開-P --partial-dir=.rsync-partial
  • 巨大ファイル多め--delete-delay で削除を最後にまとめて実行
  • 厳密検証--checksum は全ファイルを読み直すため超重い。定期運用では非推奨、スポット検証でのみ。

よくある落とし穴

  • 消えた!--delete は強力。必ず --dry-run で事前確認。
  • 隠しファイルが無い"$SRC/" を使えているか? * で展開すると漏れる。
  • 属性が保持されない:保存先のファイルシステム(FAT/exFAT等)が属性をサポートしているか確認。
  • macOS でオプションが使えない:rsync 3.x を導入(Homebrew など)で解決。
  • UIDs/GIDs がずれる--numeric-ids を付ける。

まとめ

  • rsync+cron なら、毎日のバックアップを差分だけ素早く・堅牢に自動化できる。
  • 履歴を残すなら --link-dest スナップショットが最強。容量と復元性のバランスが良い。
  • 運用前の --dry-run、運用中の 排他・ログ・ローテーション をセットで入れると事故が激減。

まずはローカルにスナップショットを作り、慣れてきたら SSH でオフサイトにも複製。今日から “壊れにくいバックアップ運用” を始めましょう。

Bash玄

はじめまして!Bash玄です。

エンジニアとしてシステム運用に携わる中で、手作業の多さに限界を感じ、Bashスクリプトを活用して業務を効率化したのがきっかけで、この道に入りました。「手作業は負け」「スクリプトはシンプルに」をモットーに、誰でも実践できるBashスクリプトの書き方を発信しています。

このサイトでは、Bashの基礎から実践的なスクリプト作成まで、初心者でもわかりやすく解説しています。少しでも「Bashって便利だな」と思ってもらえたら嬉しいです!

# 好きなこと
- シンプルなコードを書くこと
- コマンドラインを快適にカスタマイズすること
- 自動化で時間を生み出すこと

# このサイトを読んでほしい人
- Bashに興味があるけど、何から始めればいいかわからない人
- 定型業務を自動化したい人
- 効率よくターミナルを使いこなしたい人

Bashの世界に一歩踏み出して、一緒に「Bash道」を極めていきましょう!

Bash玄をフォローする

コメント