pdumpfsによる定期バックアップのススメ

最終更新日: 2004-03-30 (公開日: 2004-03-30)

Software Design誌 2003年8月号 に掲載された記事の元の原稿です。


pdumpfs*1 は毎日のス ナップショットを保存するバックアップシステムである。本稿では pdumpfs のインストール方法から使い方、仕組みまで幅広く紹介す る。

はじめに

ここ数年、ハードディスクのクラッシュにあっていない。定期的な バックアップは欠かさずに行っているが、クラッシュが起きないた め、それが役に立つ機会はほとんどない。

こうなるとバックアップなんてしなくてもいいのではないか、とい う気もしてくるが、クラッシュしたときのことを考えると、やめる わけにもいかない。また、ディスククラッシュがなくても、誤って ファイルを削除してしまったときの保険という意味でバックアップ は大切である。

私の場合は、以前に、バックアップを取っていなかったために1週 間かけて書いたソースコードをディスククラッシュで失うという痛 い目にあった。以来、バックアップを欠かさないようになった。本 稿では、毎日の定期バックアップにぴったりなツール pdumpfs を 紹介する。

pdumpfs とは

pdumpfs は次のような特徴を持ったバックアップシステムである。

毎日のスナップショットを保存する

pdumpfs を使ってバックアップをとると、毎日のバックアップがス ナップショットとしてすべて保存される。このため、後からバック アップデータが必要になったときに「何年何月何日のファイル」と 指定してファイルを取り戻すことができる。たとえば、 /home/satoru 以下のファイルを /backup にバックアップしている 場合、2003年6 月15日の時点での .emacs は /backup/2003/06/15/satoru/.emacs というファイル名でアクセス できる。

一方、cp や rsync コマンドを使って毎日のバックアップをとると、 単純な方法では前日の分しかバックアップを残すことができないた め、1週間前のファイルを取り戻したい、といった場面で不便であ る。

毎日のスナップショットを保存するというと、ディスクの消費が膨 大になるのではないかと疑問を感じるかもしないが、pdumpfsでは、 ハードリンクという仕組みを利用してディスク消費を節約している。 この仕組みについては詳しく後述する。

毎日のスナップショットを保存するというアイディアは Plan9*2 という OS の標準のバックアップシステム dumpfs から借用したものであ る。pdumpfs という名前も ``pseudo dumpfs'' (まがい物の dumpfs) という意味で命名している。

バックアップデータは普通のファイル

pdumpfs はバックアップを普通のファイルとして保存するため、バッ クアップデータが必要になった際に手軽にアクセスできる。同様に、 バックアップが正しくとれているかを確認するのも容易である。

一方、tar コマンドなどを使った方法では、バックアップデータを 復元したり確認したりする際に一定のコマンド操作を必要とするた め、面倒である。とりわけ、テープメディアを使ったバックアップ は、手順が複雑であるため、いざというときにバックアップを復元 する方法を忘れてしまっている、というトラブルが起きやすい。

pdumpfs は、通常のファイル、ディレクトリ、およびシンボリック リンクのバックアップに対応し、名前つきパイプやデバイスファイ ルなどの特殊なファイルは扱えない。

普通のコマンド

pdumpfs は普通のコマンドであるため、一般ユーザの権限で実行で きる。OSのカーネルの再構築や root 権限などを必要としない。

バックアップは一日一回

pdumpfs は一日一回のバックアップを前提としている。バックアッ プの間隔が24時間空くため、データが少しでも失われると業務に支 障がでるようなデータベースなどのバックアップには向いていない。

Unix と Windows 上で動作する

バージョン 0.6 までの pdumpfs は Unix のみに対応していたが、 開発中のバージョン 0.7 *3からは Windows の NTFS にも対応している。 Windows の FAT の場合は一応動作するものの、Unix のファイルシ ステムのハードリンクに相当する機能が備わっていないため、ディ スク消費の点で大変非効率になる。

Ruby で書かれている

バージョン 0.6 までの pdumpfs はオブジェクト指向スクリプト言 語 Ruby*4で約 200行とコンパク トに実装されている。ネットワーク越しのバックアップに対応した 開発版でも 600 行と、コンパクトな実装を保っている。

pdumpfs のインストール

pdumpfs のインストールは次のように行う。原稿執筆時点での最新 バージョンは 0.6である。

% gzip -dc pdumpfs-0.6.tar.gz | tar xvf -
% cd pdumpfs-0.6
% su
Password: (rootのパスワードを入力)
% cp pdumpfs /usr/local/bin

もし Ruby の実行ファイルが /usr/local/bin/ruby 以外にインス トールされている場合は、pdumpfs の 1行目の

#! /usr/local/bin/ruby

という行を修正する。

pdumpfs の使い方

pdumpfs の使い方は簡単である。 /home/satoru というディレクト リ以下のすべてのファイルを /backup にバックアップするには次 のように実行すればよい。

% pdumpfs /home/satoru /backup

バージョン 0.7 からは、特定のファイルをバックアップ対象から 除外するための --exclude オプションを指定できる。このオプショ ンは、一時的な作業ファイルや巨大なファイルなどをバックアップ 対象から除外するといった用途に用いる。たとえば、VMware のイ メージファイル (win2000Pro.vmdk など) を除外するには次のよう に --exclude オプションを指定する。

% pdumpfs --exclude '\.vmdk$' /home/satoru /backup

--exclude オプションの引数は正規表現で指定する。上の例では、. vmdk という文字列で終わるファイル名を正規表現で指定している。

バックアップは別のディスク上にとる

上のようにバックアップをとった場合、/home/satoru と /backup が同じハードディスク上に存在していると、ディスクがクラッシュ した際に両方のデータが同時に紛失してしまう。これではバックアッ プの意味がない。そこで、/backup を別のハードディスク上に割り 当てておけば、1台のハードディスクがクラッシュしてももう 1台 の方からファイルを取り戻すことができる。

pdumpfs の仕組み

pdumpfs はバックアップ先のディレクトリに「年/月/日」の形式で その日のスナップショットを保存する。たとえば、2003年6月15 日 に、

% pdumpfs /home/satoru /backup

のように実行した場合は、/backup/2003/06/15/satoru というディ レクトリが作成され、/home/satoru 以下のファイルがすべてコピー される。

翌日に同じコマンドを実行すると /backup/2003/06/16/satoru に スナップショットが保存される。pdumpfs はこのように毎日のスナッ プショットを年月日のディレクトリで分類することにより、過去の ファイルを日付を元に参照できるようにしている。

毎日のスナップショットの保存を cp コマンドなどですべてコピー して行うと、

といった問題があるが、 pdumpfs では、2日目以降は前日のスナッ プショットに対する差分としてバックアップを行うという方法でこ れらの問題を解決している。

具体的には、前日から更新のあったファイルのみを新たにコピーし、 更新されなかったファイルは前日のスナップショットのファイルに 対するハードリンクとして記録している。ハードリンクはディスク の容量をほとんど消費しないため、単純にファイルのコピーをする 場合と比べてディスクを大幅に節約できる。また、処理時間も短い。

下の図は、 /home/satoru に .emacs と .zshrc の2つのファイル があるときに、

  1. 2003年6月15日に pdumpfs を使ったバックアップを開始
  2. その後、 .zshrc を編集 (.emacs は変更なし)
  3. 2003年6月16日に pdumpfs でバックアップをとる

という行動をとったときの pdumpfs の挙動を表したものである。

pdumpfsの仕組み
pdumpfsの仕組み

このときのディレクトリのツリーは次のようになる。

ディレクトリのツリー
ディレクトリのツリー

ハードリンクとは

ハードリンクとは、あるファイルを別のファイル名でアクセスする ためのファイルシステムの機能である。同様の機能にシンボリック リンクがあるが、シンボリックリンクではリンク先のファイルを削 除するとリンクにアクセスできなくなるのに対し、ハードリンクで はリンク先のファイルを削除してもリンクにアクセスできるという 点が大きく異なる。

pdumpfs はハードリンクのこの性質を利用して、差分によるバック アップを実現している。このため、

% rm -rf /backup/2003/06/15/satoru

のように前日のスナップショットをごっそり削除しても /backup/2002/06/16/satoru のスナップショットは被害を受けない。

バックアップの自動化

手動でバックアップを行っているとついつい怠ってしまいがちであ る。バックアップを自動化するには Unix の cron システムを利用 するとよい。たとえば、毎朝 5時に pdumpfs で /home/satoru を /backup の下にバックアップするには

% crontab -e

を実行して次の設定を crontab に加える。

00 05 * * * /usr/local/bin/pdumpfs /home/satoru /backup >/backup/log 2>/backup/error-log

この例では /backup/log には通常のメッセージが、 /backup/error-log にはエラーメッセージが記録される。cron で 設定した時刻が経過したら、/backup ディレクトリ以下を覗いてバッ クアップが正しく行われているか確認するとよい。

ネットワーク越しのバックアップ

★追記: ssh 対応は性能の問題があったため、0.7 での対応を見送 りました。申し訳ありません。

ハードディスクを2台内蔵できないノートPCなどでは、ネットワー ク越しにバックアップをとるとよい。pdumpfs のバージョン 0.7 では、 ssh *5 を利用した、ネッ トワーク越しのバックアップに対応している。たとえば、ローカル ホストの /home/satoru をリモートホスト yellow の~/backup と いうディレクトリ*6 にバックアップするには次のように実行する。このとき、リモート ホスト yellow にもネットワーク対応版の pdumpfs がインストー ルされている必要がある。

% pdumpfs /home/satoru yellow:backup

毎日のバックアップを継続的に行うには、翌日からも同じコマンド を実行すればよい。

ネットワーク対応の仕組み

ssh を使うと、リモートホスト上のコマンドをローカルホストから 実行することができる。たとえば、リモートホスト yellow の hostname コマンドをローカルホストから実行するには、コマンド ラインから次のように指定する。

% ssh yellow hostname
yellow

pdumpfs では、ssh のこの機能を利用して、内部的に 「ssh yellow pdumpfs --server」のように、リモートホスト上の pdumpfs をサーバモードとして実行している。サーバモードとして 起動された pdumpfs は、標準入出力を用いてファイルの送受信な どの処理を行う。これは rsync*7 で行われている手 法と同様である。

標準出力を用いてプロセス間通信を行うには、なんらかのプロトコ ルを決めなければならない。pdumpfs では Ruby の Marshal とい う機能を使った簡単なプロトコルを定義して、データの送受信を行っ ている。Marshal とは、オブジェクトをバイト列に変換したり、そ のバイト列から元のオブジェクトを復元するための機能である。 Marshal を使うと、オブジェクトの種類によらず共通の方法でデー タを交換できる。Marshal を使わない場合は、数値や文字列、配列 といったオブジェクトの種類ごとにプロトコルを定義しなければな らず、実装が大変になる。

Ruby に付属の irb というコマンドを使うと、Marshal の挙動を手 軽に試すことができる。

% irb
>> a = [1, 2, 3, 4, 5]              # 配列を作って変数 aに格納
=> [1, 2, 3, 4, 5]
>> data = Marshal.dump(a)           # aをバイト列に変換して変数 data に格納
=> "\004\010[\ni\006i\ai\010i\ti\n" # このようなバイト列が得られた
>> Marshal.load(data)               # dataから元の配列を復元
=> [1, 2, 3, 4, 5]                  # 復元できた

pdumpfs の歴史

pdumpfs は当初、シェルスクリプトとして開発された。しかし、遅 すぎて使い物にならないことがすぐに判明したため、Ruby で書き 直すことした。pdumpfs は私が Ruby で書いたはじめてのプログラ ムである。

2001年2月19日に公開した pdumpfs の最初のバージョンは 200行に 満たない短いプログラムであった。以来、バージョン 0.6 までバ グ修正を中心に地道な改良を行ってきた。この間、「特定のファイ ルを除外する機能が欲しい」といった要望やパッチが寄せられたが、 もともとの実装が安直でコードに手を入れにくかったということと、 コマンドラインオプションを一切持たないという単純な仕様を保ち たい、という気持ちがあったため、せっかくいただいたパッチも採 用せずに保留していた。

そうこうしているうちに、pdumpfs 本体に取り込まれなかったパッ チは Web上の各地で公開されるようになり、これらをなんとかまと めようと思いたって開発を再開したのがバージョン 0.7 である。 開発を再開するにあたって、せっかくだから何か新しいことをしよ うと考えて、取り組んだのがネットワーク越しのバックアップへの 対応である。

おわりに

本稿では pdumpfs のインストール方法から使い方、仕組みまで幅 広く紹介した。本来は、ネットワーク対応版であるバージョン0.7 を公開してから執筆するつもりだったが、十分なテストを行うこと ができず、公開が間に合わなかったのが心残りである。来月の掲載 にまわしてもらうために、締め切りの直前に、編集部に

申し訳ありません。実は、原稿はほぼ書き上げていたのですが、
突然、ディスクがクラッシュしてしまい、バックアップを怠ってい
たため、原稿は完全に消えてしまいました!

というメールを送って、「本特集で予定していた pdumpfs 記事は 著者のディスクがクラッシュしたため、次号掲載となりました」と 告知を出してもらったらバックアップ特集のネタ的にはおもしろい んじゃないかと考えたりもしたが、そんな不謹慎なことを書いてい るたった今も不安になってバックアップ *8 をとったところである。本稿がみなさんのバックアップのお役に立 てれば幸いである。

コラム: ファイルの保存し忘れ問題

ディスククラッシュによるファイルの紛失は、pdumpfs などによる 定期的なバックアップで備えることができる。しかし、OSやアプリ ケーションの突然のフリーズによる編集中のファイルの紛失には別 の対策が必要である。ファイルの保存を忘れていたばかりに、何時 間もの作業を失ったという経験のある人は多いだろう。

この問題への現実的な対策は「ファイルをこまめに保存する」とい う方法である。Emacs や Microsoft Word など、バックアップを自 動保存する機能を備えたソフトウェアも多いが、この機能は

という不安が残るため、いまいち信用できない面がある。

この「ファイルの保存し忘れ問題」は、使いやすいソフトウェアの 条件を分析した『ヒューメイン・インタフェース』*9 という本でも取り上げられ、「ファイルの保存」という機能は廃止 して常にファイルは自動で保存するべきである、と述べられている。

私はこの主張に従って、ファイルを自動で保存するように Emacs の設定を行い、以来、「ファイルの保存」をまったく行っていない。 以前は保存のキー操作 (C-x C-s) を頻繁に行って指に負担がかかっ ていたが、自動保存を設定してからは指も疲れず、ファイルの保存 し忘れの心配も消えて大変快適である。

私は機会があるたびに、この Emacs の設定方法を紹介しているが、 実際に試してくれる人はあまり多くないようだ。詳しい設定方法は 「Emacsでファイルの自動保存」 *10 というペー ジで紹介しているので Emacs を使っている方はぜひ試していただ きたい。


Satoru Takabayashi

*1<http://0xcc.net/pdumpfs/>
*2<http://www.cs.bell-labs.com/plan9dist/>
*3本稿が掲載される頃には公開されてい る予定である。
*4<http://www.ruby-lang.org/>
*5通信を暗号化してリモートホストに安全にログイン するためのツールおよびそのプロトコルのこと。製品版は SSH社 <http:/www.ipsec.co.jp/> から購入できる。フリーの実装は <http://www.openssh.org/> から入手できる。
*6~/backup は自分のホームディレクトリの下の backup ディレクトリである。私の場合は/home/satoru/backup。
*7<http://samba.anu.edu.au/rsync/>
*8原稿はリモートのCVS リポジトリに小まめにコミットして、バックアップとしている。
*9ジェフ・ラ スキン 著, 村上雅章 訳, ピアソン・エデュケーション, 2001
*10</misc/auto-save/>