2026年07月22日

Ubuntu で Time Machine 的なバックアップ戦略を立てる

 メインマシンを Ubuntu Studio に移行しようと本格的に考えています。まず考えるべきは、バックアップ戦略です。Mac OS はここが実に優れていて、Time Machine 機能を使えば、ローカルな外付けハードディスクであろうが、ネットワークディスクであろうが、全く同じやり方で定期バックアップを取ることができます(ネットワークディスク側が対応する必要があります)。現状、うちでは QNAP TS-128A をバックアップ用のネットワークディスクとして運用しています。これに定期的に差分バックアップできて、過去にさかのぼってスナップショットを取得できる、というのがゴールです。

 Linux でスナップショットをとる、と言えば、rsync で --link-dest オプションを使う、というのが定番です。ネットワークディスクを対象に rsync するには、以下の3つの方法があります。

  1. ネットワークディスクを NFS でマウントして、ローカルディスクと同様に rsync を実行する。
  2. ネットワークディスクで SSH 接続を設定して、-e ssh オプションを使う。
  3. ネットワークディスクで rsync サーバを立てて、rsync://サーバ名/ で接続する。

 順に試してみました。1. はテスト転送だと問題なかったのですが、転送中にノートパソコンのふたを閉めてスリープ状態にすると、その後起きてこなくなりました。電源を強制的に切るしかなかった。もちろん、「バックアップ中にスリープ状態にする」のは行儀が悪いことは承知しています。でも、最終的にはバックアップは自動起動させて、「今バックアップ中かどうか」ということを特に意識せずに、使えるようにしたいわけです。強制的にスリープ状態にされたら、その時点でバックアップを中断するか、スリープを解除したときに処理を続けるようにしないといけません。というわけで、この方法は却下です。

 2.は、なぜか ACL (アクセス制御リスト)の転送がうまくいきませんでした。下のようなエラーが出ました。原因は今のところ特定できていません。サーバ側とクライアント側で rsync のバージョンが違うのが気になっていますが。

recv_acl_index: ACL_TYPE_ACCESS ACL index 46 > 1
rsync error: error in rsync protocol data stream (code 12) at acls.c(729) [Receiver=3.0.7]
rsync: connection unexpectedly closed (148 bytes received so far) [sender]
rsync error: error in rsync protocol data stream (code 12) at io.c(232) [sender=3.4.1]

 3. で進めることにしました。QNAP では、HBS3 (Hybrid Backup Sync) というアプリで、rsync サーバを有効にすることができます。

20260722-1.jpg

note(ノート)

Hybrid Backup Sync (HBS 3) の使い方を解説!よくある質問にも回答|QNAP Japan

本稿ではQNAPのバックアップアプリ Hybrid Backup Sync (HBS 3) の使い方を解説します。企業のシステム部の方から個人で利用される方まで、ひろくご参考にしていただけるはずです。 最後には弊社サポートチームへよく寄せられる質問とその回答も紹介しますのでぜひご活用ください。

 クライアント側の rsync コマンドはこのようになります。

rsync \
 --password-file=/etc/rbackup/rsync.passwd \ # パスワードを記入したファイル。パーミッションを 600 にしておくこと。
 -aHAX \              #  -a(アーカイブモード)に加えて、ハードリンク・アクセス制御リスト・拡張属性を転送。
 --info=progress2 \   #  途中経過を表示。--no-inc-recursive を加えたほうが正確な表示になるが、時間がかかるので指定しない。
 --numeric-ids \      #  uid/gid を数字で処理
 --recursive \        #  ディレクトリを再帰的に処理
 --delete \           #  転送元になくて転送先にあるファイルを削除する
 --force \            #  --delete を空でないディレクトリに対しても実施
 --stats \            #  終了時にファイル数・転送量などの統計情報を出力
 --sparse \           #  スパースファイルを特別扱い
 --exclude-from="/etc/rbackup/exclude.list" \  # 除外するファイル
 --delete-excluded \  # 除外対象のファイルも --delete の対象とする
 "/" \                #  転送元
 "rsync://rsync@192.168.1.12/LinuxBackups/snapshots/in-progress/" # 転送先

 これでバックアップできることは確認しました。転送先のディレクトリを in-progress という名前に固定しているため、途中で転送が失敗しても、次回に同じ rsync コマンドを投入すれば、続きを処理できます。

 スナップショットを残すには、もう一手間必要です。まず、バックアップが正常に終了したら、転送先の in-progress というディレクトリを、日付を表す名前に変更します。そして、次のバックアップのときに、このディレクトリ名を --link-dest オプションのターゲットに指定します。

 ここで、少し厄介なのは、『正常に終了したらリネームする」手順です。もちろん、ssh でサーバにつないでしまえばどうにでもなるのですが、せっかくなのでサーバ側は rsync の設定だけで済ませたいところです。rsync サーバには、正常終了したときに実行される post-xfer というスクリプトを指定できるのですが、このスクリプトでは「クライアント側の rsync の終了状態」を検知することができません。そこで、こんな手順を考えました。

  1. クライアント側の rsync が正常終了したことを確認する。
  2. /etc/rbackup ディレクトリの中に enable-post-xfer というファイルを作成する。
  3. /etc/rbackup ディレクトリを rsync でサーバに転送する。
  4. 転送終了して実行される post-xfer スクリプトの中で /etc/rbackup/enable-post-xfer ファイルの有無を調べ、もし存在していたら in-progress ディレクトリをリネームする。
  5. 同時に、古いスナップショットをローテーションする。「最近5日分」「その前は10日ごとに5つ」「その前は1ヶ月ごとに5つ」「その前は1年ごとに数の制限なし」を残すこととする。

 バックアップスクリプトを /etc/cron.hourly に登録して、運用してみました。初回はもちろん時間がかかります(3時間ぐらいだったと思う)。その後は、普段使いの範囲内では、1日分の差分の転送が15分程度で完結することがわかりました。なお、QNAP は 5G の WiFi で接続しています。

20260722-2.jpg

 長くなったので、スナップショットからの復旧については別記事にします(復旧できることは確認済みです)。今回作成したスクリプトは、その記事と一緒に公開する予定です。

タグ:Linux
Posted at 2026年07月22日 22:01:56
email.png