バックアップに便利なソフトウエア

バックアップは古来から重要だと言われながらついつい忘れてしまって、泣きをみる管理作業でしょう。 Take60は、NEC PC-6001で当時雑誌で提供されていたゲームを打ち込んで、 セーブせずに実行して3時間の作業がパーという状況で育ってきました。 が、大学時代管理作業をなにもやっていなかったので、 バックアップを取るという習慣は全然身につかなかったのです。 仕事をはじめて次の年に大事なデータが入ったハードディスクがふっ飛びました [1]。 これに懲り、以降はPD、その後DVD-RAMへバックアップしています。 テープを利用しないのは、ちょうどそのころod-driverがでて使えるようになったという理由の他に、マウントしてそのまま必要なものだけとってくるということを良くやるからだと思います。

今回は普段の連載の番外編としてバックアップで活躍するツールを御紹介します。

FreeBSDには標準のバックアップコマンドとして cpio, dump/restoreなどがあります。 また、tarなども広い意味でのバックアップに利用できるコマンドでしょう。 これらのコマンドについては別の所で解説があるでしょうからここでは触れません。

アーカイバ

更に、データの圧縮やアーカイブを行うためのアプリケーションはports/archiversに用意されています。 これは以前Personal UNIX No.2で桐山先生が紹介されているとおりです。 今回は各アーカイバの処理時間をTable 1にまとめました。 バックアップデバイスへの記録時間が主となるように、バックアップデバイスには低速なDVD-RAM(SCSI接続のPanasonic LF-D102)を用いました。 以降の表でもバックアップデバイスはDVD-RAMです。 バックアップ対象はFreeBSD 4.1.1Rの/usr/src以下で、GTAGSなどが転がっているものです。

時間でuserが大きいものは圧縮作業などでCPUを使っているためです。 高圧縮率のものはここが大きくなっています。 zooのファイルサイズが謎ですが、なぜでしょうか? あと、zipはうまくアーカイブできませんでした。

Table 1. アーカイバの処理時間

方法 ファイルサイズ [a] 時間 [b] コマンド備考
tar(圧縮あり)89068156(24.43%)429.78/236.79/14.55tar zcf /dist/hoge.tar.gz /usr/src 
lha105852262(29.04%) 1030.23/409.54/24.30lha aw=/usr/tmp /mo/lha.lha /usr/src 
afio345067520(94.65%)602.05/1.63/15.05find /usr/src/ -print | afio -o /mo/backup.afio 
tar(圧縮なし)364554240(100%)618.08/0.75/13.64tar cf /dist/hoge.tar /usr/src 
zoo4294967352(1178.14%)697.84/145.05/19.51find /usr/src/ -print | zoo aI /mo/backup.zoo 
Notes:
a. ()内はtarの圧縮無しとの比較。
b. 以降の時間はすべて/usr/bin/timeで計測。 左からreal(コマンドプロンプトが帰ってくるまでの時間)/user(ユーザプロセスが使った時間)/sys(システムコールで利用された時間)。

afio

afio(sysutils/afio)は基本的にはcpioフォーマットのアーカイブを作成するためのコマンドですが、さまざまな拡張が行われています。 例えば、

  • PGPを用いた暗号化アーカイブ [2]

  • 拡張子に基づく圧縮の抑制

  • コントロールファイルを用いた柔軟なアーカイブ設定

などがあげられます。 またドキュメントによると、cpioや圧縮tarを使うよりも安全にアーカイブを作成できるとなっています。

圧縮ソフトウエア

ハードディスクの低価格化と大容量化に伴って、バックアップを行うメディアも大きくなる必要があります。 ところが、ハードディスク自体を除くとランダムアクセス可能なメディアはせいぜい5Gぐらいなので、バックアップ時に圧縮する必要があります。 また、シーケンシャルなデバイスでも圧縮することでより大きなディスクのバックアップが可能となり、バックアップ時間も短縮されることが期待されます。 ここでは圧縮のためのソフトウエアの性能を比較してみます。 既にアーカイバで述べたソフトウエアもリストアップしてありますが、圧縮性能だけを見ています。

Table 2. 圧縮ソフトウエアの性能

ソフトウエアアルゴリズムファイルサイズ圧縮備考
オリジナルファイル 364554240(100%)  Table 1の圧縮無しtarファイルを利用。 オリジナルファイルはHDD上にあり、圧縮ファイルをDVD-RAMに保存した。
bzipBurrows-Wheeler-Fenwick block-sorting68884729(18.90%)977.59/894.78/6.19 
bzip2Burrows-Wheeler block sorting + Huffman coding69671653(19.11%)726.25/607.89/5.26 
lhalh5,lh683796854(22.99%)795.45/478.56/9.47 
gzipLempel-Ziv(LZ77)改89068167(24.43%)294.02/235.98/5.66 
freezeLempel-Ziv + dynamic Huffman105748362(29.01%)289.39/229.62/5.78 
lzopLZO1134441347(36.88%)224.59/22.12/6.94 
compressadaptive Lempel-Ziv(LZW)138758458(38.06%)230.70/101.81/7.44 
mscompressLempel-Ziv(LZ77)145625292(39.95%) 圧縮ファイルとオリジナルを別のディレクトリに置けない。

UFSによるバックアップ

ufsを作成可能なバックアップデバイスの場合、圧縮などの必要性がなければそのままコピーして保存しておくことも可能です。 ただし、cp -Rなどを使うと、更新する必要が無いものまでコピーされますので、無駄が多くなります。 これらを避け、更新されたファイルだけをコピーしてくれるアプリケーションとしてはcpbk(sysutils/cpbk)やrsync(net/rsync)があります。 後者はネットワーク越しの同期にも利用可能ですし、sshを使うことで安全にデータの転送を行えます。

Table 3. バックアップ方法と時間の比較

方法最初のバックアップ時間 touchした後のバックアップ時間 [a] rmした後のバックアップ時間 [b] コマンド備考
rsync 9629.53/245.82/51.65 1099.16/10.76/11.76 1012.15/7.25/8.69 rsync -az --delete /usr/src /mo/rsync  
cpbk 6924.12/1.40/26.15 1093.14 real 1.12 user 5.93 sys 899.23/1.20/4.20 cpbk -nr /usr/src /mo/cpbk 
cpdup 7028.33/12.64/35.81 759.42/6.91/6.62 839.55/5.90/5.77 cpdup -i0 /usr/src /mo/cpdup  
Notes:
a. /usr/src/sys/compile/HOGE/の全ファイルをtouchした。
b. 同じく/usr/src/sys/compile/HOGE/の全ファイルを削除した。

更新されたファイルだけをコピーする:cpbk/cpdup

cpbk(sysutils/cpbk)は更新されたファイルだけを同期するものです。 このとき、ゴミ箱(trashbin)を指定しておく(-tオプション)と、消されたファイルを残しておいてくれます。 ディレクトリツーリーを同期したい場合は-rオプションを使いましょう。 また、消されたファイルをコピー先でも消去する場合は-nオプションを指定します。

cpdup(sysutils/cpdup)も同じようなツールです。 こちらは消されたファイルはインタラクティブに聞いてきます。 問答無用で消したい場合は-i0オプションを利用すると良いでしょう。

rsync

rsync(net/rsync)はファイルの更新が局所的なことを利用して、ブロック単位で更新を比較し、更新されている部分だけを同期するソフトウエアです。 基本的にソース側からディストネーション側への一方向の同期です [3] 。 デフォルトでは転送にrshを使いますが、環境変数RSYNC_RSHを設定することでsshの利用も可能です。 バックアップを作成するためには、アーカイブモード(-a)を利用すると良いでしょう。 基本的に古き良きUNIXコマンドのように寡黙ですので、-vオプションをつけてあげないとほとんど経過は出力されません。 また、ソース側で消されたファイルをディストネーション側で消す場合は--deleteオプションが必要です。

典型的な使い方としては以下のようなものがあるでしょう。

  • ローカルでのディスクのバックアップ。

    		rsync -az /usr/ports/distfiles /mo/distfiles
    	      

  • ネットワーク越しにファイルを同期、不用なファイルは削除。

    		rsync -az --delete ‾/www hoge.co.jp:/usr/local/www/data
    	      

詳細な解説はUNiX Magazine 2000年7月号の島慶一氏の連載UNIX知恵袋で扱われています。

Unison

Unison(net/unison)はインタラクティブな双方向のファイル同期ツールです。 rsyncと同じように、ブロック分割して差分を調べる方法でファイルの変更を調べます。 portsからインストールした場合、コマンドラインインターフェースしか使えませんが、GtkによるGUIも用意されています。 基本的にファイルが更新されている場合には、その処理をどうするかをインタラクティブに指定することで同期を行います。 双方のファイルが同時に更新されている場合は、どちらのファイルにそろえるのかを選択することができます。 ドキュメントはportsでは入りませんので、Webページを参照して下さい。

基本的な使い方は

	  unison dir1 dir2
	
となります。 可能な操作は ? を押すことで一覧表示されますので、これを見ながら行えばいいでしょう。 デフォルトの動作であるf(スペース,Enterでもよい)では、新しいファイルへの同期が割り当てられています。 同時に更新されている場合は、無理にそろえないのがデフォルトの動作です。 最終的に
Proceed with propagating updates? []
	
と聞いてきますので、yを押すことで実際の同期処理が行われます。

ネットワークでの利用やGtkインターフェースのビルドなどの詳細は、UNiX Magazine 2001年3月号の山口英先生の連載「UNIX Communication Notes」を参照して下さい。

バックアップフロントエンド

定期的なバックアップにはこれまでに説明したようなアーカイバや圧縮プログラムなどを組み合わせて利用することになりますが、バックアップしたメディアの管理やネットワークでのバックアップの設定など複雑な要因はまだまだあります。 そこで、バックアップコマンドのフロントエンドとして動くシステムがいくつか開発されています。 このようなシステムには Amandaflexbackupnwclientなどがあります。 このうち、AmandaはUNIX USER 2001年1月号および2月号において、花井浩之氏による連載Setting Up FreeBSDで詳細な解説が加えられているのでここでは紹介しません。

flexbackup

flexbackup(sysutils/flexbakcup)は設定の容易なバックアップフロントエンドです。 特徴としては

  • 設定が簡単。

  • アーカイバを簡単に変えられる。 また、アーカイバごとの設定も可能。

  • バッファリングや圧縮の指定が可能。

  • リモートファイルシステムのバックアップが可能。

  • Perlで記述されている。

  • ログファイルがわかりやすい。

ドキュメントは少ないですが、/usr/local/share/doc/flexbackup/ディレクトリの設定ファイル(flexbackup.conf.sample)とflexbackup.README以外にもコマンド本体の先頭にオプションが記述されているので参照すると良いでしょう。 設定ファイルは/etc/flexbackup.confになります。 今回はサンプルの訳をつけておきます(Figure 1)。

Figure 1. flexbackup.conf.sampleの訳

# ----------------------------------------------------------------------
# Flexbackup 設定ファイル
#    Take60 <take60@i.am>による大幅な意訳
#
# Original Id: flexbackup.conf,v 1.36 1999/11/03 03:13:42 edwinh Exp 
# Original Name: v0_9_8 
#
# ----------------------------------------------------------------------
# 一般設定項目

# アーカイブタイプ?  afio, dump, tar, cpio, zip のいずれか
$type = 'afio';

# オプションで 'all' が与えられた時にダンプしたいファイルシステムの一覧
# スペースで区切られたリストにします。
# リモートファイルシステムは 'host:dir' と記述します。
#
# 例:
#   $filesystems[0] = '/ /usr /home machine1:/usr machine2:/home';
#
# 全てのレベル0バックアップを複数のテープに保存したい場合,複数行に書いて下さい。
# テープの交換が必要な場合プロンプトが出ます。
#
$filesystems[0] = '/ /var /usr goliath:/ goliath:/var';
$filesystems[1] = '/home otherhost:/bigdisk';

# 圧縮
$compress    = 'gzip';  # 以下のいずれか: false/gzip/bzip2/compress/hardware
$compr_level = '4';     # 圧縮レベル (1-9) (gzip/bzip2/zip 使用時)

# バッファ
$buffer      = 'true';  # ストリーミングを助けるために "buffer" プログラムをつかうなら true
$buffer_megs = '3';     # バッファのメモリサイズ (メガバイト)
$pad_blocks  = 'true';  # ブロックをブロックサイズに合わせるなら true

# バックアップするデバイス - 巻戻しをしないデバイスを指定すること!
#
# 例:
#    Linux SCSI: /dev/nst0       Linux IDE: /dev/nht0
#    Linux ftape: /dev/nqft0     FreeBSD SCSI: /dev/nrsa0
#
# ディレクトリを指定すると,デバイスではなくそのディレクトリのファイルへアーカイブする。
#
$device	 = '/dev/nht0';

# ブロックサイズ(k指定) (ほとんどのものに対するデフォルトは 10)
$blksize = '64';

# テープデバイスで"可変"ブロックサイズを使う時には true (mt setblk 0)
# false の場合, 上記の $blksize 変数が使われます。
# 全ての non-mt コマンドはこの値ではなく $blksizeを利用しています。
$mt_var_blksize = 'true';

# その他のグローバルフラッグ
$remoteshell = 'rsh';   # リモートシェルコマンド (rsh/ssh/ssh2)
$verbose     = 'true';  # 各ファイルをエコーするか? (fio/tar/cpio/zip 用)
$sparse      = 'true';  # 疎なファイルを扱う (afio/tar/cpio 用)
$indexes     = 'true';  # 目次(table-of-contents) サポートオフにする

# ファイルシステムを跨ってバックアップするか? ("dump" はこのオプションを無視します)
# "false" (しない) , "local" (nfs 以外), or "all" (すべて)のいずれかにします。
$traverse_fs = 'false';

# 正規表現に基づくバックアップから除外するファイル(シェルのワイルドカードではない)
# ('dump' アーカイブには影響を与えない)。
# 1つ以上を角カッコ('[',']')の中の数字を増やしていくことで列挙可能です。
# もちろん,("-fs"フラグや上での指定で与えられる)先頭のディレクトリは省略可能です。
# 何も指定しない場合はコメントアウトしてください。
$exclude_expr[0] = 'news/articles';
$exclude_expr[1] = '.*‾$';  #'# シングルクオートを使うとemacsのフォントロックが幸せ

# 圧縮しないファイルの拡張子 (スペースで区切る)
# afio と zip だけで有効 (これらのコマンドは各ファイルを個別に扱うため)
$nocompress_types = 'mp3 Z z gz gif zip lha jpeg jpg taz tgz deb rpm bz2';

# (デフォルトである)true であれば,レベル0 の "allは消して新しいテープを使います。
# false であれば他のバックアップと同じように追加します。
$erase_tape_all_level_zero = 'true';

# 本当に "mt erase" を呼ぶのではなく,消去操作時に巻戻すだけの場合、
# これを "true" に設定します。
# いくつかのテープドライブでは消去は秒ではなく何時間かかる場合があります。
$erase_rewind_only = 'false';

# ----------------------------------------------------------------------
# ログ/スタンプ(stamp)ファイル, 一時ファイルのためのパス

$logdir	  = "/var/log/flexbackup";   # ログファイルのためのディレクトリ
$stampdir = "/var/state/flexbackup"; # バックアップタイムスタンプのためのディレクトリ
$index    = "$stampdir/index";       # テープインデックスのための DB ファイル名
$comp_log = "gzip";                  # 圧縮ログ? false/gzip/bzip2/compress
$prefix	  = "";			     # ログファイルのプリフィックス
$sprefix  = "";	                     # スタンプファイルのプリフィックス
$tmpdir   = "/tmp";                  # テンポラリの refdate ファイルなどのために使われる

# なぜ stampやindex に /var/state/flexbackup を例示しているのでしょうか?
# FHS, http://www.pathname.com/fhs/2.0/fhs-5.11.html を見て下さい。
# BSD ユーザは 多分 /var/db/flexbackup を使いたいでしょう。

# ----------------------------------------------------------------------
# 'afio' だけに関するパラメータ

# ブロック番号を表示する時に true
$afio_echo_block = 'false';

# (キロバイト指定の)このサイズより小さいファイルは圧縮しません
$afio_compress_threshold = '3';

# 圧縮結果の一時記憶に使う為の(メガバイト指定の)最大メモリ。
# 圧縮ファイルがこのサイズよりも大きい場合,圧縮はファイルに対して2度行われます(マニュアル参照)。
$afio_compress_cache_size = '2';

# ----------------------------------------------------------------------
# 'tar' のためのパラメータ

# レコード番号を表示する場合 true
$tar_echo_record_num = 'false';

# ファイルの更新時間を保存する場合 true
$tar_atime_preserve = 'true';

# ----------------------------------------------------------------------
# 'cpio' のためのパラメータ

# cpioアーカイブのフォーマット
$cpio_format = 'newc';

# ----------------------------------------------------------------------
# 'dump' のためのパラメータ

# (キロバイト指定の)推定テープサイズ。
# この数字はあまり重要ではないですが、
# 推定のサイズを得ることは 'dump' を助けます。
# 0 に設定された場合 'dump -a' を使います。
$dump_length = '0';

# /etc/dumpdates を使う場合 true
# falseの場合 flexbackup のタイムスタンプを利用します。
$dump_use_dumpdates = 'false';

# ----------------------------------------------------------------------
# 'zip' のためのパラメータ


######################################################################
# perl の 'require' のために、次の行は'1' のままにしておくこと。
1;

	

Notes

[1]

最初の年はクーラの無い部屋で、しかも最上階だったので肉体もコンピュータも相当なダメージを受けていたようです。

[2]

実は、圧縮プログラムをPGPに置き換えるだけですが…

[3]

オプション-uなどをうまく使えば時間的に最新のものに同期することは可能です。