TT Lab
はじめる
学ぶ 学習パス コース

バックアップとリストア

tarとrsyncを正確に使う

TT Labで続きを見る

一言でいうと

tarは時点を保存するツールで、rsyncは状態を揃えるツールです。バックアップ設計では、2つは競合ではなく役割分担です。

なぜ必要なのか

「バックアップはtarでやりますか、rsyncでやりますか」という質問に、決まった答えはありません。世代ごとのアーカイブが必要ならtar、最新状態のコピーが必要ならrsyncです。そして実務の構成の大半は、両方を使います。

どう動くのか

tar

tar -czf /backup/etc-$(date +%F).tar.gz --acls --xattrs --selinux --numeric-owner -C / etc
tar -tzf /backup/etc-2026-08-20.tar.gz | head
tar -xzf /backup/etc-2026-08-20.tar.gz -C /restore/

オプションの正確な意味です。

復元時は、パスを必ず確認してください。 -C /でそのまま展開すると、現在のシステム設定を上書きします。安全な手順は、一時的なパスに展開して内容を確認してから、必要なファイルだけを移すことです。

mkdir -p /restore/etc-check
tar -xzf /backup/etc-2026-08-20.tar.gz -C /restore/etc-check
diff -r /restore/etc-check/etc/nginx /etc/nginx | head -40

GNU tarとBSD tar(bsdtar)は、オプションの扱いや一部の動作が異なります。macOSで作ったアーカイブをLinuxで展開するときに、拡張属性に関するファイルが一緒に出てくる問題が代表的です。バックアップスクリプトは、実際の本番ディストリビューションで検証する必要があります。

rsync

rsync -aHAX --numeric-ids --delete --dry-run /srv/data/ backup@10.0.9.2:/backup/prod/data/

世代バックアップは、ハードリンクで安く作れます。

rsync -aHAX --numeric-ids --delete --link-dest=/backup/prod/daily.1 /srv/data/ /backup/prod/daily.0/

各世代はフルのスナップショットのように見えますが、ディスクを占めるのは変更分だけです。

2つのツールの役割分担

必要なこと ツール
特定時点のアーカイブファイル1つ tar
オフサイトへ移す単一のオブジェクト tar(+圧縮、暗号化)
最新状態のコピーの維持 rsync
世代ごとのスナップショットを安く rsync --link-dest
帯域幅を節約したリモート同期 rsync(デルタ転送)

現場での姿

--deleteによる事故です。元のデータが空だったり、マウントが外れた状態で実行されると、コピー先のデータをすべて消します。実務で実際に繰り返される事故です。ガードが必須です。

世代バックアップを、ハードリンクを知らないツールでコピーして、容量が3倍になる事故もあります。-Hは-aに含まれません。

転送の途中でずれないようにする

tarとrsyncは単純に見えますが、大容量のデータを移すときに、静かにずれてしまう箇所があります。

変更中のファイルをそのまま保存すると壊れます。 tarは、読み取りの途中でファイルが変わるとfile changed as we read itという警告を出し、そのファイルだけが壊れた状態のまま先へ進みます。サービスを止められないなら、スナップショット(LVM、ファイルシステム、クラウドボリューム)を取って、それを保存します。

ハードリンクとスパースファイルを保存します。 オプションなしに移すと、ハードリンクがそれぞれ別のコピーになって容量が何倍にもなり、スパースファイルは0で埋められて膨れ上がります。

tar --numeric-owner --acls --xattrs --sparse -cf - /srv | zstd -T0 > srv.tar.zst
rsync -aHAX --sparse --numeric-ids /srv/ backup:/srv/

-aだけでは、ハードリンク(H)・ACL(A)・拡張属性(X)は引き継がれません。SELinuxのラベルは-Xに含まれています。

途中で切れても再開できるようにします。 --partial --append-verifyを指定すると、再開するときに最初から受信し直しません。大きなファイル1つを何日もかけて移すときに、差が大きく出ます。

末尾のスラッシュの有無で結果が変わります。 rsync -a /src/ /dst/は中身を移し、rsync -a /src /dst/は/dst/srcを作ります。スクリプトでは、この1文字のせいでパスが1階層深くなる事故が繰り返されます。

削除するときは、先に目で確認します。 --deleteは、コピー先にだけあるものを削除します。コピー元のパスが間違っていると、コピー先をまるごと空にしてしまいます。

rsync -aHAX --delete --dry-run --itemize-changes /src/ /dst/ | head -50

検証は別のステップです。 rsyncは転送中にチェックサムを使いますが、あとでファイルが傷んだかどうかは教えてくれません。一覧とハッシュを一緒に残しておけば、数か月後にも確認できます。

find /srv -type f -print0 | sort -z | xargs -0 sha256sum > manifest.sha256
sha256sum -c manifest.sha256 --quiet

次のラボですること

tarでフル・増分・除外・分割を扱い、rsyncでdry-run・ガード・世代バックアップ・負荷制御を扱います。どちらのラボも、最後に結果を検証します。