rdiff-backupを使ってシステムのバックアップ

rdiff-backupはファイルのバックアップに使うツールです。 (様々な*nixシステム上で使えます)。

特に書いていない限り、下記のコマンドはコンソールからrootとして実行します

*(単に個々のファイルを回復するだけでなく)dist-upgradesやカーネルのアップグレードがうまくいかなかった時などの混乱した状況からシステム全体を回復するのにとても役に立ちます。
*rsyncと同じく変更のあったところだけをバックアップします(そのため実行時間がそれほど長くかかりません)。
*変更履歴を保持します(つまり三週間前に消去してしまったファイルなども回復できるということです!)
*(sshを使って)ネット上で安全なバックアップもできます。
*マウントされているパーティションをバックアップします。 (アンマウントする必要がないので毎日のバックアップなどを簡単に自動化できます)。
*ハードドライブが壊れて新しいものに交換したときもすべてのファイルを回復できます。
*大きなネットワークシステムのバックアップ用(LinuxはOKですが、Windowsには向きません)にもスケールできるためビジネスに使われています。
*コマンドラインのアプリなので自動的で強力なバックアップツールが好きな人にピッタリ(cronからbashスクリプトを呼ぶ)。
*ファイルのオーナーやパーミッションも保存し、シンボリックリンク(その他いろいろ)も保存するのでデータの回復の際には保存したときの状態を再現できます。

必要なのは...

rdiff-backupはファイルのコピーをそのまま(圧縮なしで)保存し、さらに編集履歴も保存(増分バックアップ)するためバックアップ先のスペースは元のスペース以上に必要になります。 たとえば100Gbのスペースのデータをバックアップするのに120Gbが必要となるかもしれません。 (なるべく別ディスクに保存しましょう!))。

セッティング

一例として次のようなPCだったとしましょう:
* 100Gbのハードドライブ(sda)を使用。 sda1がrootパーティションで、sda5は音楽などのファイルのスペース、sda6がスワップ。
* 200Gbの予備ハードディスク(sdb)はsdb1だけマウントしてある... これをバックアップスペースとして使います。
* IPアドレスは192.168.0.1

まずはrdiff-backupのインストール:

# apt-get install rdiff-backup

個々のディレクトリのバックアップもできますが、ここではパーティション全体のバックアップを行います... sda1とsda5をバックアップするため(hd6のバックアップは要りません)まずデータを保持するディレクトリを作ります:

# mkdir -p /media/sdb1/rdiff-backups/192.168.0.1/root
# mkdir -p /media/sdb1/rdiff-backups/192.168.0.1/sda5

IPアドレスを使うのは(後述しますが)ここに他のコンピュータのデータもバックアップする場合に備えてです。

バックアップ

rdiff-backupはrdiff-backup source-dir dest-dirのシンタックスを使います。 ノート: ファイル名ではなく、常にディレクトリ名を書きます。

sda5をバックアップするコマンド:

# rdiff-backup /media/sda5 /media/sdb1/rdiff-backups/192.168.0.1/sda5

rootパーティションをバックアップするコマンド:

# rdiff-backup --exclude '/tmp/*' --exclude '/proc/*' --exclude '/sys/*' --exclude '/media/*/*' / /media/sdb1/rdiff-backups/192.168.0.1/root

AF_UNIX path too long"というエラーメッセージが表示されても無視して構いません。 初めての時はすべてのファイルをバックアップするので少々時間がかかるかもしれません。 常に変動する/tmpや、実際にはファイルを含まない/procや/sysといったディレクトリを除いていることに注目してください。 マウントされている他のディスクもバックアップ対象から外してあります。 マウントされているディスクを含めてしますとバックアップ先のsdb1もコピーしようとするので無限ループになってしまいます! これを避けるのにマウントを一つずつバックアップするという方法もあります。

ここで'/proc'ではなく'/proc/*'が使われているのはこれによって/procというディレクトリの名はバックアップに含めつつディレクトリの内容は無視するためです。 /tmpや/sysの場合も同じです。 /mountの場合もほとんどトリックといえますが、マウントポイントの名前までバックアップしてその内容は無視します。

こうすればrootパーティションに問題が起こってバックアップからパーティション全体を回復するときは自動的に/tmp, /proc, /sysやマウントポイント名も回復します。 (これがないと困ったことになります。 たとえばXがスタートする時にもし/tmpディレクトリがなかったら、エラーメッセージがでるかもしれません。 --excludeと--includeについてはmanページを読んでください)。

バックアップからディレクトリを回復するには

rdiff-backupは次のようなシンタックスで使います:

rdiff-backup -r <いつから> <どこのディレクトリから-dir> <バックアップ先のディレクトリ>

たとえばうっかりして/media/sda5/photosを消去してしまった場合、これを回復するには:

# rdiff-backup -r now /media/sdb1/rdiff-backups/192.168.0.1/sda5/photos /media/sda5/photos

ここで"-r now"は最新のバックアップから回復するオプションです。 もしシステムが(crontabなどを使って)定期的にバックアップされていて、photosディレクトリを消してしまったことに何日か気づかずに過ごしてしまった場合、最新ではなく、数日前のバックアップから回復することになります。 (最新のバックアップからだと、photosというディレクトリはないと言うでしょう) それとも単に古いバージョンのファイルが見たい時もあるでしょう。

3日前のバックアップから回復するには"-r 3D"のオプションを使います... ただ、manページにも書いてあるように 注意:

"-r 3D"というのは現在の72時間前という風に解釈され、もしその時点までのバックアップがなかったら、その一つ前のバックアップが使われます。 例として"-r 3D"が使われたけれど2日前と4日前のバックアップしかない場合はディレクトリは4日前の状態に回復します。 (コマンドを実行するまえにちょっと考えましょう。)

sda5がバックアップされた日時を表示するコマンドは:

# rdiff-backup -l /media/sdb1/rdiff-backups/192.168.0.1/sda5
パーティションの回復

パーティション全体を回復することもできます。 結局のところマウントポイントとはディレクトリなわけですから。

警告: rootパーティションの回復はそのパーティションで起動中には行わないこと! 一つのコマンドで他のドライブのバックアップまで含めた全部のファイルを失うことになるかもしれません! rdiff-backupは言われたとおりのことを正確に実行するだけです... もしrootパーティションのバックアップが空っぽのマウントポイントだったら、その状態に回復するためにすべてのファイルを消去してしまいます。

sda5を最新のバックアップから回復するコマンドは:

# rdiff-backup -r now /media/sdb1/rdiff-backups/192.168.0.1/sda5 /media/sda5
rootパーティションの回復

しかしrootパーティションを回復するのはそれほど単純ではありません。 rootパーティションは決してマウント中に回復しないように(上の警告を参照)。 しかしrootパーティションの回復はとくにアップデートの失敗や新しいカーネルのインストールの問題などの時に、問題が起きる以前の状態に戻せるというのは大変便利なことです。 しかもそれが20分程度でできるのですから。 .

rootパーティションを回復する一つの方法はハードディスクに予備のLinuxパーティションがあればそれををrootとして起動することです。 そうすれば回復しようとするパーティションはrootではないので、普通のコマンドが使えます。 パーティション回復の作業が終わったら改めてそれをrootとして起動すればバックアップした時とまったく同じ状態で起動します。 そう、まったく同じです。 これがなんといっても一番簡単な方法です。

rootパーティションを回復するもう一つの方法はaptosidのライブCDから起動してそこからパーティションの回復作業を行うことです。 rdiff-backupはaptosidに含まれていますから。 もしrdiffを含まないバージョンのaptosidライブCDだった場合は、起動時のGrubの起動オプションに"unionfs"と入力して起動すると、ライブCDのシステムにアプリケーションをインストール出きるようになります。 そのように起動したあと、次のようにコマンドを実行します。:

$ sudo su
# wget -O /etc/apt/sources.list http://aptosid.com/files/misc/sources.list
# apt-get update
# apt-get install rdiff-backup
やっとデータ回復のコマンドです:
# mount /dev/sda1 /media/sda1
# mount /dev/sdb1 /media/sdb1
# rdiff-backup -r now /media/sdb1/rdiff-backups/192.168.0.1/root /media/sda1

ノート: aptosidのCDがなくてもklikにサポートされたライブCDがあれば、klikを使ってrdiff-backupをインストールできます:

$ sudo ~/.zAppRun ~/Desktop/rdiff-backup_0.13.4-5.cmg rdiff-backup -r now /media/sdb1/rdiff-backups/192.168.0.1/root /media/sda1

不測の事態に備えてrootパーティションをバックアップしている人は、あらかじめ回復作業をテストしておくべきです。 バックアップしてあるから大丈夫だと思っていて、緊急の時になって予期しない問題に直面することほどひどいことはありません。

If the hard drive has been changed or reformatted, recheck the UUIDs, (or Labels), in /boot/grub/menu.lst (grub-legacy) or files in /etc/grub.d (grub2) and /etc/fstab, and alter accordingly. An easy way to get the information to alter the menu.lst and fstab files, if required, is as root:

blkid
他のPCのデータのバックアップ

sshの接続さえ可能ならば、他のPCのデータをバックアップすることもできます。 (もう一つの条件として、当然バックアップ先のPCには十分なハードディスクスペースが必要です) リモート側のPC上にsshサーバー(sshd)が走っている必要があります。 2台のPCが同じLANに接続されている必要はなく、2台が世界中のどこにあっても同じです。

仮に次のようなリモートPCがあったとしましょう:
1) 100Gbのハードドライブ(sda)の
2) sda1がrootパーティションで
3) sda5にはバックアップの必要のないテンポラリファイルがあり
4) sda6はスワップ
5) IPアドレスは192.168.0.2

ノート: 普通二つの100Gbドライブはrdiff-backupで200Gbのドライブにバックアップすることは(増分のデータを保存するスペースがないため)できませんが、上のリモートPCのhd5はバックアップの対象からはずれているため何とかバックアップできると計算できます。(もう一つハードディスクがいつも100%使われているわけではないという点もありますが、そこはアテにしない方が無難です)。 rdiff-backupが行われるたびに増分のデータが増えていってスペースがどんどん使われていきます。

rdiff-backupに最大1ヶ月分までバックアップさせるように設定することもできます。 (コマンドは後述)こうすればrdiff-buckupに一年分のデータをバックアップさせるよりずっと小さいスペースで済みます。 一年分のデータを保存するためには一年分の増分ファイルを保存できるハードディスクが必要ということになります。

まず初めにすることはリモートPCにrdiff-backupをインストールすることです。 (バックアップサーバーも含めてバックアップに使うコンピュータすべてにrdiff-backupがインストールされていなければなりません

リモートPCのデータをローカルPCに保存するにはローカルPC(ここではie 192.168.0.1)上で次のコマンドを実行します: 二重のコロン :: の使用に注目

# mkdir /media/sdb1/rdiff-backups/192.168.0.2/root
# rdiff-backup --exclude '/tmp/*' --exclude '/proc/*' --exclude '/sys/*' --exclude '/media/*/*' 192.168.0.2::/ /media/sdb1/rdiff-backups/192.168.0.2/root

今度はリモートPCのディレクトリを回復するにはローカルPCからでもリモートPCからでもコマンドを実行できます。

リモートPCの /usr/local/games をリモートPCからのコマンドで回復するには:

# rdiff-backup -r now 192.168.0.1::/media/sdb1/rdiff-backups/192.168.0.1/root/usr/local/games /usr/local/games

リモートPCの /usr/local/games をローカルPCからのコマンドで回復するには:

# rdiff-backup -r now /media/sdb1/rdiff-backups/192.168.0.1/root/usr/local/games 192.168.0.2::/usr/local/games

ライブCDを起動してrootのパーティションの修復をするときも同じようなシンタックスを使います。(リモートPCがライブCDで起動されている場合は上の例をみてください。

自動バックアップ:

他のPCのデータをバックアップしたい場合、まず初めにするのはsshキーを使ってパスワードなしでsshログインできるようにすることです。 rootとしてパスワードなしでsshログインするわけですが、rdiff-backupのコマンドだけを実行するように設定することもできます。 詳しいことはここでは触れませんのでSSHの設定のページをご覧ください。 ここでは完全な信用があることを想定してパスワードなしのsshログインの一番簡単な設定法を紹介します。

ローカルPC上で次のコマンドを実行します:

# [ -f /root/.ssh/id_rsa ] || ssh-keygen -t rsa -f /root/.ssh/id_rsa

そして空のパスワードとしてEnterキーを二回押し、次に:

# cat /root/.ssh/id_rsa.pub | ssh 192.168.0.2 'mkdir -p /root/.ssh;\
> cat - >>/root/.ssh/authorized_keys2'

ここでrootのパスワードを入力するように求められます。

これでリモートPCにパスワードをタイプせずにsshログインできるようになりました。 これでrdiff-backupも自動化できます。

次にrdiff-backupのコマンドを丸ごと含んだbashスクリプトを作ります。 次のような内容になります:

#!/bin/bash
RDIFF=/usr/bin/rdiff-backup
echo
echo "=======Backing up 192.168.0.1 root======="
${RDIFF} --ssh-no-compression --exclude '/tmp/*' --exclude '/proc/*' --exclude '/sys/*' --exclude '/media/*/*' / /media/sdb1/rdiff-backups/192.168.0.1/root
echo "(and purge increments older than 1 month)"
${RDIFF} --remove-older-than 1M --force /media/sdb1/rdiff-backups/192.168.0.1/root
echo
echo "=======Backing up 192.168.0.1 mount sda5======="
${RDIFF} --ssh-no-compression --exclude /media/sda5/myjunk /media/sda5 /media/sdb1/rdiff-backups/192.168.0.1/sda5
echo "(and purge increments older than 1 months)"
${RDIFF} --remove-older-than 1M --force /media/sdb1/rdiff-backups/192.168.0.1/sda5
echo
echo "=======Backing up 192.168.0.2 root======="
${RDIFF} --ssh-no-compression --exclude '/tmp/*' --exclude '/proc/*' --exclude '/sys/*' --exclude '/media/*/*' --exclude '/mnt/*/*' 192.168.0.2::/media/sdb1/rdiff-backups/192.168.0.2/root
echo "(and purge increments older than 1 months)"
${RDIFF} --remove-older-than 1M --force /media/sdb1/rdiff-backups/192.168.0.2/root

このbashスクリプトに"myrdiff-backups.bash"のような名前をつけてローカルPC(バックアップ先のPC)の /usr/local/bin に置き、chmod +xで実行ファイルにします。 一度実行してちゃんと作動することを確認しましょう。

最後にこれを毎晩8時にcronから実行するようにセットします。 rootのcrontabに次の行を加えるだけです。

# crontab -e
そして次の行を入力します
0 20 * * * /usr/local/bin/myrdiff-backups.bash
Page last revised 14/08/2010 0100 UTC