リポジトリの保守

Subversion リポジトリの管理はぞっとするような仕事になること もあります。大部分はデータベースバックエンドのもつシステムから引き継い だ複雑さによります。作業をうまくこなすには、とにかくツールについて深く理解する ことです—そのようなツールがいったい何であり、いつ使えば、またど うやって使えばよいのかを知ることです。この節ではSubversionによって提供 されるリポジトリ管理用ツールを紹介し、リポジトリの移行、更新、バックアッ プ、クリーンアップのような作業でどうやって使いこなせばよいかを説明しま す。

管理者用ツールキット

Subversion はリポジトリの作成、調査、修正、修復に便利なユー ティリティーをいくつも提供しています。それぞれについてもっと詳し く見てみましょう。その後 Berkeley DB のディストリビューションに含 まれるユーティリティーのいくつかを簡単にためしてみます。 Berkeley DB は Subversion 自身のツールとしては提供していないリポ ジトリデータベースバックエンドに特化した機能を提供しています。

svnlook

svnlookはSubversionが提供するツールで リポジトリ中のいろいろなリビジョンやトランザクションを調査 するのに使われます。このプログラムのどの部分もリポジトリを 変更することはありません—これは単なる「読み出し専用 」のツールです。 svnlookは典型的には、まさにコミットされようとして いる変更を報告したり(pre-commit フック)、 コミット直後の報告(post-commitフック)のために リポジトリフックによって使われます。リポジトリ管理者は診断のために このツールを使うこともできます。

svnlook は単純な構文です:

$ svnlook help
general usage: svnlook SUBCOMMAND REPOS_PATH [ARGS & OPTIONS ...]
Note: any subcommand which takes the '--revision' and '--transaction'
      options will, if invoked without one of those options, act on
      the repository's youngest revision.
Type "svnlook help <subcommand>" for help on a specific subcommand.
…

ほとんどのsvnlookのサブコマンドは リビジョンかトランザクションツリーのどちらかに対して働き、 ツリー自身の情報か、以前のリポジトリのリビジョンとの違いを 表示します。--revision--transaction オプションを使ってどの リビジョンまたはトランザクションについて調査するかを指定する ことができます。リビジョン番号は自然数として表示されますが、 トランザクション名称は英数字の文字列だということに注意してください。 ファイルシステムはコミットされていないトランザクションのみを表示 できることを憶えておいてください(新しいリビジョンを作れなかった トランザクション)。ほとんどのリポジトリにはそのようなトランザクション はありません。トランザクションは普通、コミットされる(そうすると 見えなくなります)か、中断後、削除されるからです。

--revision--transaction も指定しないと、 svnlook は最新の(あるいは「HEAD」) リビジョンをリポジトリの調査対象とします。それで、以下の二つの コマンドは/path/to/reposにあるリポジトリで 19が最新リビジョンである場合はまったく同じ意味になります:

$ svnlook info /path/to/repos
$ svnlook info /path/to/repos --revision 19

サブコマンドに関する唯一の例外はsvnlook youngest で、これはオプションをとらず、単に、HEADリビジョンの番号を表示します。

$ svnlook youngest /path/to/repos
19

svnlook の出力は人間にも マシンにも理解できるように設計されています。 info サブコマンドを例にします:

$ svnlook info /path/to/repos
sally
2002-11-04 09:29:13 -0600 (Mon, 04 Nov 2002)
27
Added the usual
Greek tree.

info サブコマンドの 出力は、以下のように定義されています:

  1. 作業者、改行

  2. 日付、改行

  3. ログメッセージの長さ、改行

  4. ログメッセージ自身、改行

この出力は人間が読むことができます。日付のタイムスタンプ などは、何かバイナリ表現のようなものではなく、テキスト形式になっています。 しかし、これはまたマシンも解析できる形式のものです— ログメッセージは複数行にわたることができ、長さの制限がないので、 svnlook はメッセージ自身の前にその長さを 表示します。これで、このコマンドのスクリプトやほかのラッパープログラムは 賢い判断ができるようになります。たとえば、メッセージにどれだけの メモリを割り当てれば良いか、とか、イベント中で少なくとも何バイト スキップしてもデータストリームの終わりにならないか、などを知ることが できます。

よくある別の svnlook の使い方はリビジョンまたは トランザクションツリーの実際の内容を見ることです。 svnlook tree コマンドは要求されたツリー中の ディレクトリとファイルを表示します。--show-idsオプション を指定するとそれらのパスごとのファイルシステムノードリビジョン ID も 表示します(そのようなパスは一般的に言ってユーザよりも開発者に有用なもの でしょう)。

$ svnlook tree /path/to/repos --show-ids
/ <0.0.1>
 A/ <2.0.1>
  B/ <4.0.1>
   lambda <5.0.1>
   E/ <6.0.1>
    alpha <7.0.1>
    beta <8.0.1>
   F/ <9.0.1>
  mu <3.0.1>
  C/ <a.0.1>
  D/ <b.0.1>
   gamma <c.0.1>
   G/ <d.0.1>
    pi <e.0.1>
    rho <f.0.1>
    tau <g.0.1>
   H/ <h.0.1>
    chi <i.0.1>
    omega <k.0.1>
    psi <j.0.1>
 iota <1.0.1>

ツリー中のディレクトリのファイルの構成が理解できればsvnlook cat, svnlook propget, そして svnlook proplistのようなコマンドを 使ってそれらのファイルやディレクトリについてのより詳細な情報を 取得することができます。

svnlook は他にもいろいろな問い合わせをしたり、 いままで説明した情報の一部を表示したり、指定したリビジョンや トランザクションのどのパスが修正されたかを報告したり、ファイルや ディレクトリに対するテキストや属性の相違点を表示したり、などなど ができます。以下はsvnlookが理解できる現時点 でのサブコマンドの簡単な説明の一覧と、その出力です:

author

そのツリーの実行者です

cat

ツリーの特定のファイルの内容を表示します。

changed

ツリー中で変更のあったファイルとディレクトリの一覧

date

ツリーのタイムスタンプです

diff

変更されたファイルの unified diffの表示

dirs-changed

ツリー自身に変更があるか、その子供のファイルに変更が あったディレクトリの一覧表示

history

バージョン化されたパスの履歴中での、興味深い場所の表示 (どこで変更やコピーが起きたかを示します)。

info

ツリーの変更者、タイムスタンプ、ログメッセージ文字数、そして ログメッセージの表示

lock

パスがロックされている場合にロックの属性を表示します。

log

ツリーのログメッセージの表示

propget

ツリー中のパスに設定された属性値を表示します。

proplist

ツリー中のパスに対して設定された属性の名前と値を表示します。

tree

ツリーの一覧表示をします。オプションでそれぞれのパスに 結びついたファイルシステムノードリビジョンのIDを 表示します。

uuid

リポジトリの UUID — つまり Universal Unique IDentifier(普遍的に一意な識別子) を表示します。

youngest

最新のリビジョン番号を表示します。

svnadmin

svnadmin プログラムはリポジトリ管理者によって 一番よく利用されます。Subversionリポジトリを作成することのほか このプログラムはリポジトリに対してさまざまな保守操作をします。 svnadmin の構文は、svnlook のものとよく似ています:

$ svnadmin help
general usage: svnadmin SUBCOMMAND REPOS_PATH  [ARGS & OPTIONS ...]
Type "svnadmin help <subcommand>" for help on a specific subcommand.

Available subcommands:
   create
   deltify
   dump
   help (?, h)
…

既にsvnadmincreate サブコマンドを見てきました(リポジトリの作成と設定項参照)。 他のサブコマンドのほとんどをこの章の後のほうで説明します。いまは 利用可能なサブコマンドの全体を軽く見ておきます。

create

Subversionリポジトリを新規に作成します。

deltify

リビジョン範囲を指定して実行すると、それらの リビジョンで変更されたパス上で祖先の差分を計算します。リビジョンが指定 されなければこのコマンドは単に HEAD リビジョンの差分を計算します。

dump

指定範囲のリビジョンのリポジトリの内容をダンプ します。ポータブルダンプ形式で出力します。

hotcopy

リポジトリのホットコピーをとります。いつでも実行することが でき、他のプロセスがリポジトリを利用しているかどうかにかかわらず、安心して リポジトリのコピーをとることができます。

list-dblogs

(Berkeley DB リポジトリの場合のみ)リポジトリに関係したBerkeley DBログファイルのパスを一覧表示します。 このリストはすべてのログファイルを含みます—現在Subversionが利用しているもの、もう 利用していないものも含みます。

list-unused-dblogs

(Berkeley DB リポジトリの場合のみ)リポジトリに関係したBerkeley DBログファイルで、既に利用していない もののパスを一覧表示します。そのようなログファイルはリポジトリレイアウトから 安全に削除することができますが、リポジトリの壊滅からの復旧には必要となる事態にそなえて アーカイブすることもできます。

load

データストリームから、リビジョンの集まりをリポジトリにロードします。 データストリームはdump サブコマンドで生成されたのと 同じポータブルダンプ形式です:

lslocks

リポジトリに存在するロックを説明つきで一覧表示します。

lstxns

現時点でリポジトリに存在しているコミットされていない Subversionトランザクションの名前を一覧表示します。

recover

必要に応じてリポジトリの回復ステップを実行します。普通は リポジトリとの間の通信をきれいに終了できなかったプロセスによって 起きた致命的なエラーの後で実行します。

rmlocks

一覧されたパスからロックを無条件に取り除きます。

rmtxns

リポジトリからSubversionトランザクションをきれいに削除します。 (lstxns サブコマンドからの出力をこの プログラムに入力すると便利です)

setlog

リポジトリ中の指定リビジョンのsvn:log (コミットログメッセージ)属性の値を新しい値で置き換えます。

verify

リポジトリの内容を確認します。これはリポジトリに格納されたバージョン化された データのチェックサム比較、なども含まれます。

svndumpfilter

Subversion は非公開のデータベースシステムにすべてのデータを格納 しますが、簡単には手で修正することができないようにするためです。 実際にはそれほど難しいことでもないのですが。そしてデータがリポジトリに いったん格納されてしまうと、Subversion はそのようなデータを削除する ための簡単な機能を提供してはいません。 [15] しかし、時にはどうしてもリポジトリの履歴を操作したいことがあります。 リポジトリに間違って追加してしまったすべてのファイル(あるいはどんな 理由であれとにかくそこにあるべきではないファイル)を削除したいと思う かも知れません。あるいは一つのリポジトリを共有する複数のプロジェクト があって、それぞれを固有のリポジトリに分割することに決めたのかも 知れません。このような作業のためには、管理者はリポジトリ中のデータ のより柔軟に管理可能で柔軟な表現形式が必要です—それは Subversion のリポジトリダンプフォーマットです。

Subversion のリポジトリダンプフォーマットは時間とともにバージョン化 されたデータに加えた変更点に対する可読な形の表現形式です。ダンプ データを生成するにはsvnadmin dumpを使い、 新たらしいリポジトリにそれをロードするにはsvnadmin load を使います(リポジトリの移行項参照)。ダンプ形式が可読な形で あることの大きな利点は、注意して扱えばそれを調べたり修正したりできること です。もちろん、欠点としては、もし二年分のリポジトリ内容が一つの巨大な ダンプファイルに保存されているような場合には特定の場所を見つけて修正 するには非常に、非常に長い時間がかかるであろうことです。

管理者が自由にしたい場合に最もよく利用されるツールというわけでは ありませんが、 svndumpfilterは非常に特殊な 役に立つ機能を提供しています—パスベースのフィルタとして 実行することによってそのダンプデータをすばやく簡単に修正することが できるのです。保存したいと思うパスのリストか、保存したくないパスの リストを単に与えてこのフィルタにリポジトリのダンプデータをパイプで 入力するだけです。結果は、あなたが(明示的、あるいは暗黙に)要求した バージョン化されたパスのみを含むような修正済みダンプデータになります。

svndumpfilter の構文は以下のものです:

$ svndumpfilter help
general usage: svndumpfilter SUBCOMMAND [ARGS & OPTIONS ...]
Type "svndumpfilter help <subcommand>" for help on a specific subcommand.

Available subcommands:
   exclude
   include
   help (?, h)

興味深いサブコマンドは二つだけです。これらのサブコマンドを使って、 ストリーム中で明示的に、あるいは暗黙に取得するパスを選ぶことができます。:

exclude

ダンプデータストリームから特定のパスを排除します。

include

ダンプデータストリームから、指定したパスだけを 出力するようにします。

このプログラムが実際にどのように動作するか例を見てみましょう。 別の場所でリポジトリ中でどのようにレイアウトを選ぶかを決める手順について 議論しました(リポジトリレイアウトの選択項)—プロジェクトごとの リポジトリ、あるいはそれらをまとめたものを使って、リポジトリ中で構成を 変更し、などの手法です。しかし、新しいリポジトリが運用されたあとで、 よくレイアウトを再編成していくつかの修正をしたいということもあります。 一番多いのは一つのリポジトリを共有していた複数のプロジェクトを プロジェクトごとの別々のリポジトリに分離したい、という場合です。

私たちの架空のリポジトリは三つのプロジェクトを含んでいます: calc, calendar, そして spreadsheetです。 それらは以下のようなレイアウトになっています:

/
   calc/
      trunk/
      branches/
      tags/
   calendar/
      trunk/
      branches/
      tags/
   spreadsheet/
      trunk/
      branches/
      tags/

これら三つのプロジェクトごとの固有のリポジトリを手に入れるには、 まずリポジトリ全体をダンプします:

$ svnadmin dump /path/to/repos > repos-dumpfile
* Dumped revision 0.
* Dumped revision 1.
* Dumped revision 2.
* Dumped revision 3.
…
$

次に結果のダンプファイルをフィルタに通しますが、各実行時で ただ一つの最上位ディレクトリを含むように指定することで、 三つの新しいダンプファイルを生成することができます:

$ cat repos-dumpfile | svndumpfilter include calc > calc-dumpfile
…
$ cat repos-dumpfile | svndumpfilter include calendar > cal-dumpfile
…
$ cat repos-dumpfile | svndumpfilter include spreadsheet > ss-dumpfile
…
$

この時点で、判断しなくてはなりません。上でできた三つのダンプファイルは 正しいリポジトリですが、元のリポジトリ中にあった通りのパス構成で保存されて います。これはcalcプロジェクト単独のリポジトリを 取得したにもかかわらず、リポジトリはあいかわらずcalc という名前の最上位ディレクトリ名称を持っていることを意味します。 もしtrunk, tags, そして branchesディレクトリそれぞれをリポジトリ のルートディレクトリとしたければダンプファイルを編集してNode-pathCopyfrom-pathヘッダがもうこれからは先頭に calc/というパス部分を持たないようにしなくてはなりません。 同様にcalcディレクトリを作ったダンプデータのセクションを 削除したいでしょう。それは何か以下のような感じになっています:

Node-path: calc
Node-action: add
Node-kind: dir
Content-length: 0

警告

もし最上位ディレクトリを削除するためにダンプファイルを手で編集しようと 考えているなら、利用するエディタが改行文字を自動的にマシン固有の形式に 変換してしまわないことを確認してください(たとえば ¥r¥n を ¥n などに)。 この変換が起きるとダンプファイルの内容はメタデータと一致しなくなり、使 い物にならなくなってしまいます。

この修正後に残ったファイルを使って新しい三つのリポジトリを作成する ことができ、それぞれのダンプファイルを正しいリポジトリにロード することができます:

$ svnadmin create calc; svnadmin load calc < calc-dumpfile
<<< Started new transaction, based on original revision 1
     * adding path : Makefile ... done.
     * adding path : button.c ... done.
…
$ svnadmin create calendar; svnadmin load calendar < cal-dumpfile
<<< Started new transaction, based on original revision 1
     * adding path : Makefile ... done.
     * adding path : cal.c ... done.
…
$ svnadmin create spreadsheet; svnadmin load spreadsheet < ss-dumpfile
<<< Started new transaction, based on original revision 1
     * adding path : Makefile ... done.
     * adding path : ss.c ... done.
…
$

svndumpfilterの両方のサブコマンドとも 「空の」リビジョンをどのように扱うかを決めることが できます。パスの変更のみを含んでいるようなリビジョンを除外 すれば、空のリビジョンは興味がないか、不要なものであると 考えることができます。svndumpfilterは 以下のコマンドラインオプションを用意しています:

--drop-empty-revs

空のリビジョンを生成しません— 単に無視します。

--renumber-revs

空のリビジョンが削除された場合に(--drop-empty-revsを 利用することによって)、残っているリビジョンのリビジョン番号を変更して リビジョン番号が飛ばないようにします。

--preserve-revprops

空のリビジョンが削除されない場合に、それら空のリビジョンに関する リビジョン属性(ログメッセージ、変更者、日付、カスタム属性、など)を 保存します。そうでなければ、空のリビジョンは元のタイムスタンプと、 このリビジョンはsvndumpfilterによって空にされた ということを示す自動生成されたログメッセージのみを含むことになります。

svndumpfilter は非常に便利で、作業を省力化して くれますが、残念なことにいろいろな問題もあります。まずこのユーティリティー はパスの構文に極端に敏感です。ダンプファイル中のパスが先頭にスラッシュ を含んでいるかどうかに注意してください。Node-pathCopyfrom-pathヘッダを確認する必要がある かも知れません。

…
Node-path: spreadsheet/Makefile
…

パスの先頭にスラッシュがある場合、svndumpfilter includesvndumpfilter excludeに渡す パスの先頭にスラッシュを含める必要があります(そして、逆にスラッシュが ないなら含めてはいけません)。さらにダンプファイルの先頭のス ラッシュが何かの理由で矛盾している場合には [16] おそらく、すべてをスラッシュ付きにするか、その逆にするような正規化を パスに対して施す必要があります。

また、コピーされたパスは問題を起こすかも知れません。Subversionは リポジトリ中のコピー操作をサポートしていて、ここでは新しいパスは 既に存在するパスからコピーすることによって作成されます。リポジトリの 生存中のどこかでファイルあるいはディレクトリをsvndumpfilter が排除するようなどこかの場所からコピーし、svndumpfilter が含めるような場所にコピーしたかも知れません。ダンプデータに自己一貫性を 保証するためsvndumpfilterは新しいパス— コピーによって作られた任意のファイルの内容を含むような— を表示 する必要がありますが、それはダンプデータストリームから排除された 存在しないようなソースからのコピーの追加としては表示されません。 しかし Subversion のリポジトリダンプ形式はそれぞれのリビジョンで何が変更 されたかを示すだけなので、コピー元の内容は利用不可能です。もし リポジトリ中でこのようなコピーがある可能性がある場合にはもう一度 svndumpfilterに含めるパスと排除するパスを 再考する必要があるかも知れません。

Berkeley DB ユーティリティー

Berkeley DB リポジトリを使っている場合は、バージョン化されたファイルシ ステム構造とデータ全体はリポジトリの db サブディレクトリにあるいくつかのデータベーステーブルに保存されています。 このサブディレクトリは通常の Berkeley DB 環境ディレクトリで、どのよう な Berkeley データベースツールとも組み合わせて使うことができます(これ らのツールに関するドキュメントはSleepyCat のウェブサイトhttp://www.sleepycat.com/にあります)。

通常のSubversion の利用ではこれらのツールは不要です。Subversion リポジトリ に必要なほとんどの機能はsvnadminを使って実行する ことができます。たとえばsvnadmin list-unused-dblogssvnadmin list-dblogsは Berkeley の db_archiveで提供されている機能のサブセットであり、 svnadmin recoverdb_recover ユーティリティーの普通の状況での利用の仕方を反映したコマンドです。

それでもいくつかの Berkeley DB ユーティリティーは知っていると便利です。 db_dumpdb_load プログラムはBerkeley DB データベース のキーと値を表現するカスタム形式ファイルの読み書きを実行します。 Berkeley データベースはマシンアーキテクチャをまたいだ互換性 があるので、この形式はアーキテクチャやOSの違いを意識せずに データベースマシン間で転送するのに便利な方法です。また、 db_statユーティリティーは Berkeley DB 環境の 状態についての有用な情報を表示します。これにはサブシステムの ロックやデータ保存についての詳細統計情報が含まれます。

リポジトリのお掃除

Subversionリポジトリは一般的にいったん設定してしまえばほとんど 注意を払う必要はありません。しかし、管理者による、いくつかの 補助が必要かも知れません。svnadmin ユーティリティー には以下のような作業を助けるための機能があります。それは

  • コミットログメッセージの修正。

  • 死んだトランザクションの削除。

  • 固まってしまった」 リポジトリの復旧。

  • リポジトリの内容を別のリポジトリに移すこと。

svnadminのサブコマンドで一番よく使われるのは 多分 setlogです。トランザクションがリポジトリに コミットし、リビジョンを表示したとき、新しいリビジョンに関連した ログメッセージは、そのリビジョン自体のバージョン化されない属性として 格納されます。言い換えると、リポジトリはその属性の最後の値だけを 記憶していて、以前のものは捨ててしまいます。

ときどきユーザはログメッセージに間違いを見つけます(スペルミスや 間違った情報など)。もしリポジトリが( pre-revprop-changepost-revprop-change フックを使って。 フックスクリプト項参照) コミット完了後このログメッセージの変更を受け付けるとすると ユーザは、svn プログラムの propsetコマンドを使ってログメッセージを ネットワーク越しに「修正」 することができます。 (章 9. Subversion リファレンス参照) しかし、情報が永久に失われてしまうことを防ぐため、Subversion リポジトリはデフォルトではそれをさせません。デフォルトは、 バージョン化されない属性は、管理者のみが変更することが できます。

もしログメッセージを管理者が変更する必要がある場合、 svnadmin setlogを使います。このコマンドは リポジトリの指定したリビジョンのログメッセージ(svn:log 属性 )を、用意したファイルから新しい値を読み出し形で変更します

$ echo "Here is the new, correct log message" > newlog.txt
$ svnadmin setlog myrepos newlog.txt -r 388

svnadmin setlog コマンドだけでは、リモートクライアント としてバージョン化されていない属性を修正する場合と同じ制約を 受けます—つまりpre-post-revprop-change フックはやはり実行され、この仕組みで変更される修正点は反映されて しまいます。しかし管理者はこのような保護機能をsvnadmin setlog コマンドに--bypass-hooksを指定することで回避できます。

警告

しかしフックを回避すると、属性変更、バージョン化されていない属性変更 を追うためのバックアップシステム、などなどに関係した通知 メール も 回避されてしまうことに注意してください。言い換えると、何を、どのように 修正するかについて、非常に注意して実行してください。

別のよくある svnadmin の使い方は終了していない —多分死んでしまった—Subversionトランザクションに関する リポジトリへの問い合わせです。コミットが失敗したとき、普通 トランザクションはきれいに消去されます。つまりトランザクション はリポジトリから削除され、そのトランザクションに(だけに)関連した データも同様に削除されます。 しかし、しばしばトランザクションの掃除が起こらずに失敗することが あります。これにはいくつかの理由が考えられます: 多分クライアントの 操作がユーザによって乱暴に終了されたか、ネットワークの異常などが 処理の途中で起こった場合です。理由にかかわらず、死んだままの トランザクションが残ることはありえます。ディスクをわずかに食うことを のぞけば、このようなトランザクションは全く無害です。それでも 潔癖な管理者はこのようなトランザクションを削除したいと思うかも 知れません。

svnadminlstxns コマンド を使って、その時点での未完了のトランザクションの名前の一覧表示 することができます。

$ svnadmin lstxns myrepos
19
3a1
a45
$

出力結果のそれぞれの項目はsvnlook (とその--transaction オプション)で 使うことができ、誰がトランザクションを作り、それは いつで、どのような変更がトランザクションに起きたか、を 知ることができます。 —言い換えると、そのトランザクションは削除対象として 安全な候補なのかどうか、ということをです。もしそうなら、 トランザクションの名前をsvnadmin rmtxns に渡すことができ、そのトランザクションはきれいに削除 されます。rmtxns サブコマンドは、 lstxnsの出力をそのまま入力として とることもできます!

$ svnadmin rmtxns myrepos `svnadmin lstxns myrepos`
$

このような二つのサブコマンドを使う場合、リポジトリを一時的に クライアントからアクセスできなくする必要があります。 これで誰もあなたがクリーンアップを始める前に正しいトランザクション を開始できなくなります。以下は、リポジトリ内の未解決のトランザクション のそれぞれについての情報をすばやく生成するためのちょっとした スクリプトです:

例 5.1. txn-info.sh (未解決トランザクションの表示)

#!/bin/sh

### Generate informational output for all outstanding transactions in
### a Subversion repository.

REPOS="${1}"
if [ "x$REPOS" = x ] ; then
  echo "usage: $0 REPOS_PATH"
  exit
fi

for TXN in `svnadmin lstxns ${REPOS}`; do 
  echo "---[ Transaction ${TXN} ]-------------------------------------------"
  svnlook info "${REPOS}" --transaction "${TXN}"
done

このスクリプトを /path/to/txn-info.sh /path/to/reposのように して実行できます。出力は基本的にはsvnlook info 出力のいろいろな断片をつないだようなものになります。 (svnlook項参照), 以下のような 感じです:

$ txn-info.sh myrepos
---[ Transaction 19 ]-------------------------------------------
sally
2001-09-04 11:57:19 -0500 (Tue, 04 Sep 2001)
0
---[ Transaction 3a1 ]-------------------------------------------
harry
2001-09-10 16:50:30 -0500 (Mon, 10 Sep 2001)
39
Trying to commit over a faulty network.
---[ Transaction a45 ]-------------------------------------------
sally
2001-09-12 11:09:28 -0500 (Wed, 12 Sep 2001)
0
$

長く放置されているトランザクションは普通は何かに失敗したか、コミットを 中断されたかのどちらかです。トランザクションの日付スタンプは 役に立つ情報を与えてくれます — たとえば 9 ヵ月も前に始まった 操作がいまだに有効である可能性など、いったいどの程度あるのでしょうか?

簡単に言って、トランザクションのクリーンアップの決定は、無分別に やる必要はありません。いろいろな情報源—Apacheのエラーログや アクセスログ、成功したSubversionのコミットログ、などなど—が どうしたら良いかを決める上で役に立ちます。最後に、管理者はしばしば 死んだトランザクションの所有者と思われる人と、(メールなどで)その 死にかかったトランザクションの状態を確認することができます。

ディスク領域の管理

ここ数年で記憶装置のコストは非常に低くなってきた一方で、ディスクの利用方法 は、大量のデータをバージョン管理するために、システム管理者にとっては、やはり 依然として考慮すべきことです。動作中のリポジトリによって消費される追加の 領域はオフラインでバックアップすることが必要な領域でもあり、バックアップ のスケジュール管理を考えると、何倍かになるでしょう。Berkeley DB リポジ トリを使う場合には、データ保管の仕組みは複雑なデータベースシステムである ので、データのどの部分をオンラインのままに残し、どの部分にバックアップが 必要で、どの部分を安全に削除できるか、ということについて理解しておくことには 意味があります。 この節は Berkeley DB だけに関係しています。FSFS リポジトリには削除したり、 調整が必要な特殊な追加データはありません。

最近まで、Subversion リポジトリに関して最も多くディスクを消費する部分は Berkeley DB が実際にデータベースファイルを修正する前に前もっと書き込むための ログファイルの領域でした。これらのファイルはデータベースのある状態から 別の状態への変化の経緯にそったすべての操作を記録します— データベース ファイルはある特定の時刻にその状態を反映される一方でログファイルはその前後 の状態のすべての本稿を含んでいます。そのようなわけでログファイルは非常に 早いスピードでサイズを増やします。

ありがたいことに、Berkeley DB のリリース 4.2 からデータベース環境は 特に外部操作することなしに未使用のログファイルを削除する能力を持つ ようになりました。Berkeley DB バージョン 4.2 かそれ以降でコンパイルされた svnadminはこの自動的なログファイルの削除が設定 されています。この機能を有効にしたくない場合には単に svnadmin createコマンドで--bdb-log-keep を渡してください。これを忘れたり、後で変更したい場合には、単に リポジトリのdbディレクトリ中にあるDB_CONFIG を編集して、set_flags DB_LOG_AUTOREMOVEディレクティブをコメントアウトしてから この変更を強制的に有効にするためにそのリポジトリに対してsvnadmin recover を実行してください。データベースの設定についての詳細は Berkeley DB の設定項を参照してください。

このような自動ログファイル削除の仕組みを利用しなければ、 リポジトリを利用するにつれてログファイルは蓄積されていきます。 それてこれは実際にデータベースシステムであれば当然付いている機能です— ログファイル以外に何も残っていないような状況でデータベース全体を再構成する ことができるようになっていなくてはならず、そのようなログファイルは データベースの壊滅的な破壊からの復旧で利用できなければならないからです。 しかし普通は Berkeley DB で既に利用されていないログファイルをアーカイブし、 その後ディスクから削除することで領域を広げようとするでしょう。利用していない ログファイルの一覧を見るにはsvnadmin list-unused-dblogsコマンドを使ってください:

$ svnadmin list-unused-dblogs /path/to/repos
/path/to/repos/log.0000000031
/path/to/repos/log.0000000032
/path/to/repos/log.0000000033

$ svnadmin list-unused-dblogs /path/to/repos | xargs rm
## disk space reclaimed!

リポジトリのデータサイズをできるだけ小さくするために Subversion は リポジトリに対して差分化(あるいは「 差分記憶」) の処理をします。差分化は別のデータの部分に対する 差分の集まりをひとつのデータの塊として表現するものです。二つのデータ が非常に似ていればこの差分化は差分化されたデータの記憶領域を節約します —もとのデータサイズと同じだけの領域を確保するのにくらべて小さく なります。いわば、「以下の変更点をのぞけば、他の点についてはここに あるデータのままですよ」という表現に必要なだけの領域で済みます。 具体的に言うと、ファイルの新しいバージョンがリポジトリにコミットされる たび、Subversion は前のバージョン(実際には前のバージョンのいくつか)を この新しいバージョンに対する差分として表現します。その結果、大きくなり がちなリポジトリデータ—つまりバージョン化されたファイルの内容 —の大部分を、もとの「完全なテキスト」として 保存するよりはずっと小さなサイズで格納することができます。

注意

差分化の対象となるすべての Subversion リポジトリデータは単一の Berkeley DB データベースファイルに保存されるので保存されているデータのサイズを 小さくしたからといって必ずしもデータベースファイル自身のサイズを減らす ことにはなりません。しかし Berkeley DB はデータベースファイル中の未使用 領域の内部的な記録を保存しておりデータベースファイルのサイズを拡張する 前にそのような領域をまず利用します。そのため差分化は直接に空間の節約につな がりはしなくても今後のデータベースサイズが拡大するスピードを有効に押える ことができます。

リポジトリの復旧

Berkeley DB項で触れたように、Berkeley DB リポジトリは正しく閉じられなかった場合には中間的な状態に固まってしまう ことがあります。こうなった場合管理者はデータベースを以前の一貫した状態 にまで戻してやる必要があります。

リポジトリ中のデータを保護するため Berkeley DB はロックのしくみ を利用しています。このしくみはデータベースの特定のが同時に複数のデータベー スアクセスによって修正されないことを保証するためのもので、それぞれのプ ロセスから見たときには、読み込み時にはデータは正しい状態にあるように見 えます。データベース中のどこかを変更する必要ある場合にはまず対象となる データがロックされていないかどうかを確認します。もしロックされていなけ ればそのプロセスはデータをロックし、必要な修正を加え、そのデータに対す るロックを外します。他のプロセスはデータベースの内部に引き続きアクセス できるようになる前にロックファイルが削除されるまで待たされます。

Subversionリポジトリを使う上で、致命的なエラー(ディスクがいっぱいに なったり、メモリがなくなったり)や、割り込みによって、データベースに かけたロックを削除する機会をなくしてしまうことがあります。その結果 バックエンドのデータベースは「固まって」しまいます。 こうなったときには、リポジトリへのどのようなアクセスも永久に待たされる ことになってしまいます。(というのは、すべての新しいアクセスはロック が解除されるのを待ちますが、それは決してやってこないからです)

まず、そういうことがリポジトリに起こっても、悲鳴をあげないで ください。Berkeley DBのファイルシステムはデータベーストランザクション とチェックポイント、それに事前ジャーナル書き込みの仕組みをうまく 利用していて、本当に破滅的な出来事以外は [17] データベース環境を永久に葬り去ることはできないことを保証します。 十分神経質なリポジトリ管理者は何んらかの方法でリポジトリデータの オフラインバックアップをとっているかも知れませんが、バックアップテープを リストアしてくれとシステム管理者を呼ぶのはまだです。

次に、以下の手順を使って、リポジトリの「復旧」 を試してみてください:

  1. リポジトリにアクセスしている(あるいはしようとしている)プロセスが 一つもないことを確認してください。ネットワークアクセス可能な リポジトリでは、これは Apache HTTP サーバをシャットダウンする ことも意味します。

  2. リポジトリを所有し、管理しているユーザになってください。 これは重要ですが、実行時と同様、復旧時に間違ったユーザで作業する ことによってもリポジトリファイルのパーミッションが変更されて しまうかも知れないからです。これによって実際には「復旧」 したのにアクセス不能のままになってしまう可能性があります。

  3. svnadmin recover /path/to/reposコマンドを 実行してください。以下のような出力が表示されると思います:

    Repository lock acquired.
    Please wait; recovering the repository may take some time...
    
    Recovery completed.
    The latest repos revision is 19.
    

    このコマンドは完了までに数分かかることもあります。

  4. Subversionサーバの再起動

この方法はほとんどのリポジトリロックを解消します。このコマンドは 単に rootになるのではなく、データベース を所有し、管理しているユーザで実行することに注意してください。 復旧作業は、傷を負ったいろいろなデータベースファイル からの再作成の作業も含みます。(たとえば共有メモリ領域などです) root での復旧は、root が 所有しているファイルを作成することで、これはリポジトリへの 接続状況が復旧した後でも通常のユーザはこれに対してアクセスする ことができないことを意味します。

もしいま述べた作業が、何かの理由でうまくリポジトリを正常に 戻せない場合、二つのことをすべきです。まず、壊れたリポジトリを どけて、最後のバックアップをリストアします。それからSubversion のユーザリストにメールします。(これは、 です)このとき問題点を詳しく 説明してください。データの一貫性は、Subversion開発者にとって 非常に高いプライオリティです。

リポジトリの移行

Subversionファイルシステムはさまざまなデータベーステーブルに分散された データを持ちますが、これは一般的にはSubversion開発者だけが知っている (て、興味のある)ことです。しかし、すべての、あるいは一部のデータを 一つの、持ち運びに便利な単純なファイル形式にまとめたいことがあります。 Subversion はそのような仕組みをsvnadmin サブコマンド の組によって実装しています: dumploadです。

Subversionリポジトリをダンプしたりロードしたりする一番よくある理由は Subversion自身の変更にあります。Subversion が完成に近づくにつれ、 バックエンドデータベースのスキーマ変更によっては リポジトリの前のバージョンとの互換性がなくなってしまいます。 ダンプとロードが必要になる他の理由としては、Berkeley DB を他の OS や CPU アーキテクチャに以降する場合、あるいはBerkeley DB と FSFS バックエ ンド間を切り替えて使う場合です。このために推奨されている作業ステップは比較 的簡単です:

  1. 現行 バージョンのsvnadmin を使ってリポジトリをダンプファイルにダンプしてください。

  2. Subversionの新しいバージョンへのアップグレード。

  3. 古いリポジトリをどけて、新しい空のリポジトリをそこに作りますが、 これには新しい svnadmin を使ってください。

  4. もう一度新しいsvnadminを 使って、ダンプファイルを、それぞれ作ったばかりのリポジトリに ロードしてください。

  5. 古いリポジトリから新しいものに必要なカスタマイズ部分を すべてコピーしてください。これにはDB_CONFIG ファイルと、フックのスクリプトが含まれます。新しいリリースの Subversionのリリースノートに注意して、最後のアップグレードでフック や設定オプションに変更がないかどうかを見てください。

  6. もし移行によってリポジトリが別の URL からアクセスされるようになった場 合(例えば別のコンピュータに移したり、別のスキーマを経由して アクセスしたりするような場合)、おそらくユーザには既存の作業 コピー上でsvn switch --relocateを実行する ように言わなくてはならないかも知れません。 svn switchを見てください。

svnadmin dump は、リポジトリリビジョンのある 範囲を出力しますが、それはSubversionのカスタムファイルシステム ダンプ形式になっているものです。ダンプ形式は標準出力に表示され、 進行状況などのメッセージは標準エラー出力に表示されます。これで 出力をファイルにリダイレクトすることができ、その一方でステータス の出力については端末ウィンドウ上で見ることができます。たとえば:

$ svnlook youngest myrepos
26
$ svnadmin dump myrepos > dumpfile
* Dumped revision 0.
* Dumped revision 1.
* Dumped revision 2.
…
* Dumped revision 25.
* Dumped revision 26.

処理の最後で、指定した範囲のリポジトリリビジョンのデータすべて が保存された一つのファイル(前の例では、dumpfile) を手に入れることができます。 svnadmin dumpは他の「読み出し」プロセス(たとえばsvn checkout など)がやるのと同じような 方法でリポジトリからリビジョンツリーを読み出すことに 注意してください。そのため、このコマンドはいつでも安全に実行できます。

組になったもう一方のサブコマンドであるsvnadmin loadは、標準入力を、Subversionリポジトリのダンプファイルと して解析し、ダンプされたリビジョンを目的のリポジトリに再現します。 それはまた経過情報などを返しますが、こちらは標準出力に 表示します:

$ svnadmin load newrepos < dumpfile
<<< Started new txn, based on original revision 1
     * adding path : A ... done.
     * adding path : A/B ... done.
     …
------- Committed new rev 1 (loaded from original rev 1) >>>

<<< Started new txn, based on original revision 2
     * editing path : A/mu ... done.
     * editing path : A/D/G/rho ... done.

------- Committed new rev 2 (loaded from original rev 2) >>>

…

<<< Started new txn, based on original revision 25
     * editing path : A/D/gamma ... done.

------- Committed new rev 25 (loaded from original rev 25) >>>

<<< Started new txn, based on original revision 26
     * adding path : A/Z/zeta ... done.
     * editing path : A/mu ... done.

------- Committed new rev 26 (loaded from original rev 26) >>>

load の結果、新しいリビジョンがリポジトリに追加されます—これは 通常の Subversion クライアントからリポジトリに対してコミットをする のと同じ効果があります。またやはりコミットと同様に load 処理中に おきるそれぞれのコミットの前後で実行するフックスクリプトを使うことも できます。 svnadmin load--use-pre-commit-hook--use-post-commit-hook オプションを渡すことでロードされるリビジョンごとに Subversion に 対してそれぞれ pre-commit と post-commitのフックスクリプトを実行する ように指示できます。これで例えば、通常のコミット時と同様の妥当性チェック のようなステップをロードされるリビジョンごとに保障するような使い方が できます。もちろんこのようなオプションの利用には注意が必要です— post-commit フックスクリプトで新しいコミットごとにメーリングリストに対して email を送信するようになっていた場合、リビジョンがロードされるたびに リストに数え切れないくらいの email を流したいとは思わないでしょう ! フックスクリプトについては フックスクリプト項 により詳しい情報があります。

svnadmin は標準入力と標準出力をリポジトリのダンプ とロード処理に使うので、気の利いた人は、以下のようなやり方を試す こともできます(おそらく、パイプの両側のsvnadmin は、異なるバージョンであるかも知れません):

$ svnadmin create newrepos
$ svnadmin dump myrepos | svnadmin load newrepos

デフォルトではダンプファイルは非常に大きくなります—リポジトリ 自体よりもずっと大きくなるでしょう。理由はすべてのファイルのすべての バージョンは、ダンプファイル中では完全なテキストとして表現される からです。これはダンプデータをパイプ経由で他のプロセス(圧縮プログラム や、フィルタープログラム、あるいはロードプロセスのようなもの)に送る場合には もっとも早く単純な方法です。しかし長期保存用にダンプファイルを作成する のであれば --deltasスイッチを使ってディスク領域を節約 したほうが良いでしょう。このオプションを使うと引き続くリビジョン間の ファイルは圧縮された形のバイナリ差分として出力されます—これはちょ うどリポジトリ中に保存されたリビジョンファイルと同じような形になります。 このオプションを使うと処理は遅くなりますが結果のダンプファイルは 元のリポジトリにかなり近いサイズにまでなります。

前に注意したようにsvnadmin dump はリビジョンの範囲を出力します。 --revision オプションを使えば、一つの リビジョンのダンプや、リビジョン範囲のダンプができます。 このオプションを省略すれば、すべての存在するリポジトリ リビジョンがダンプされます。

$ svnadmin dump myrepos --revision 23 > rev-23.dumpfile
$ svnadmin dump myrepos --revision 100:200 > revs-100-200.dumpfile

Subversionはそれぞれの新しいリビジョンをダンプするのでその出力には 後で実行されるローダが前のリビジョンを元にしてそのリビジョンを再 作成するのに必要な十分な情報があります。 言い換えると、ダンプファイル中でどのようなリビジョンが指定されても リビジョン中で変更のあったアイテムのみがダンプに現れるということ です。この規則の唯一の例外は、現在のsvnadmin dump がダンプする最初のリビジョンです。

デフォルトでは、Subversionは前のリビジョンに対する単なる差分として 最初のダンプリビジョンを表現することはありません。この理由の一つは 、ダンプファイルには直前のリビジョンがないからです! 二番目にSubversion はダンプデータがロードされるリポジトリの状態について何も知らない からです。(もしロードが起こるとすれば、ですが。) svnadmin dump の個別の実行の出力が自己充足して いるのを保証するため、最初のダンプリビジョンはデフォルトでは すべてのディレクトリ、ファイル、リポジトリにあるそのリビジョンの属性 の完全な表現になっています。

しかし、このデフォルトの振る舞いを変えることもできます。リポジトリを ダンプするときに--incremental オプションを追加すると svnadmin は最初のダンプリビジョンとリポジトリ中の 直前リビジョンとの差分をとろうとします。残りのすべてのダンプ されるリビジョンにも同じ方法で扱います。 それからダンプ範囲にある残りのリビジョンが出力するのと同じように 最初のリビジョンを—リビジョン中に起こる変更だけを 考慮して出力します。 この利点は大きな一つのダンプファイルのかわりに、ロードに成功するような 小さないくつものダンプファイルを作ることができることです。 こんな感じです :

$ svnadmin dump myrepos --revision 0:1000 > dumpfile1
$ svnadmin dump myrepos --revision 1001:2000 --incremental > dumpfile2
$ svnadmin dump myrepos --revision 2001:3000 --incremental > dumpfile3

これらのダンプファイルは以下のようなコマンドの流れで 新しいリポジトリ中にロードされます:

$ svnadmin load newrepos < dumpfile1
$ svnadmin load newrepos < dumpfile2
$ svnadmin load newrepos < dumpfile3

--incremental オプションを使った別の かっこいい方法は、既に存在しているダンプファイルに 新しいダンプリビジョン範囲を追加することです。たとえば post-commit フックがあり、それは単に フックをトリガーするような一つのリビジョンのリポジトリ ダンプを追加するものです。あるいは最後にスクリプトを実行した時点より 後にリポジトリに追加されたすべてのリビジョンに対してのダンプファイルを追加する ようなスクリプトを実行するかも知れません。このように利用することで svnadmindumpload コマンドは 価値のある手段となりますが、これによって、リポジトリの変更を 時間をかけてバックアップして、システムクラッシュや、他の壊滅的な出来事に そなえるというわけです。

ダンプ形式はまたさまざまな異なるリポジトリの 内容を単一のリポジトリにマージするために利用することもできます。 svnadmin load--parent-dirオプションを使って ロードプロセス用の新たな仮想ルートディレクトリを指定することが できます。これは、もしcalc-dumpfile, cal-dumpfile, そして ss-dumpfileという三つのリポジトリ のダンプファイルがある場合、最初にそれらすべてを保持するような 新しいリポジトリを作ることができることを意味します:

$ svnadmin create /path/to/projects
$

それから三つの以前のリポジトリのそれぞれの内容を含んだ 新しいディレクトリをリポジトリ中に作ります:

$ svn mkdir -m "Initial project roots" ¥
      file:///path/to/projects/calc ¥
      file:///path/to/projects/calendar ¥
      file:///path/to/projects/spreadsheet
Committed revision 1.
$ 

最後に個々のダンプファイルを新しいリポジトリのそれぞれの 場所にロードします:

$ svnadmin load /path/to/projects --parent-dir calc < calc-dumpfile
…
$ svnadmin load /path/to/projects --parent-dir calendar < cal-dumpfile
…
$ svnadmin load /path/to/projects --parent-dir spreadsheet < ss-dumpfile
…
$

Subversion リポジトリダンプ形式の利用方法について最後にもう一つだけ 触れます— 異なる保存の仕組みやバージョン管理システムから データを変換する方法です。これができる理由はダンプファイル形式は ほとんどの部分が可読であるためです。 [18] このファイル形式を 使うと、比較的簡単に一般的な変更点のセットを表現することができます— それぞれの変更は新しいリビジョンとして扱われます。 事実、cvs2svnユーティリティー(CVS から Subversion へのリポジトリ変換項参照)は、CVS リポジトリの内容を表現するのに ダンプ形式を使うので、その内容を Subversion リポジトリに取り込むことができます。

リポジトリのバックアップ

現代的なコンピュータが生まれてから技術的には非常に発展してきたものの、 残念なことに、一つのことだけは間違いなく真実です—ときどき、ものごとは まったく台無しになってしまう、ということです。停電、ネットワーク切断、 RAMの破壊、ハードディスクのクラッシュは、魔物以外の何者でもありません。 運命は最も優れた管理者にさえ降りかかるのです。それで、とても重要な トピックに行き着きます—どうやってリポジトリのバックアップを とるか、です。

一般的に、Subversionのリポジトリ管理者にとって、二つのバックアップ方法が あります—差分バックアップと、フルバックアップです。この章の前の節で どうやってsvnadmin dump --incremental を使って差分 バックアップをとるかを議論しました (リポジトリの移行項参照)。本質的にこのアイディアは最後に バックアップをとってから起きたリポジトリの変更部分だけをバックアップ する方法です。

リポジトリのフルバックアップは文字通りリポジトリディレクトリ全体の 複製を作ることです(これはBerkeleyデータベース環境も含まれます) さて、一時的にリポジトリに対するすべてのアクセスを禁止しなければ、 単純な再帰的なディレクトリコピーの実行は、不完全なバックアップを作って しまう危険を持っています。というのは誰かが並行してデータベースに書き込んで いるかも知れないからです。

Berkeley DB の場合、Sleepycat のドキュメントは正しいバックアップコピーを 保証するようにデータベースファイルをコピーする場合の順序が書いて あります。同様の順序が FSFS データにもあります。しかしこのよう なプログラムを自分で書く必要はありません。Subversion 開発チー ムがすでにしているからです。 hot-backup.py スクリプトはSubversionのソース パッケージのtools/backup/ ディレクトリにあります。 リポジトリパスとバックアップ位置を指定すると、hot-backup.py —それは単にsvnadmin hotcopyコマンドのより賢い ラッパープログラムでしかありませんが— は、動作中のリポジトリをハックアップするのに必要なステップを実行します —あなたにリポジトリアクセスを禁止することなしに、です— ついでに、動作中のリポジトリから、死んでいる Berkeley ログファイルを きれいに削除します。

差分バックアップがあるとしても、規則的にこのプログラムを実行したく なるかも知れません。たとえばhot-backup.py を プログラムスケジューラに追加しようと考えるかも知れません (Unix であればcrond のようなもの)。 あるいは、細かい粒度のバックアップが好きなら、hot-backup.py を呼ぶような、post-commitフックスクリプトを書くこともできます。 (フックスクリプト項参照)。これは新しいリビジョンが 作られるたひにリポジトリの新しいバックアップができる方式です。 単に、以下を動作中のリポジトリディレクトリにある hooks/post-commit に追加してください:

(cd /path/to/hook/scripts; ./hot-backup.py ${REPOS} /path/to/backups &)

結果のバックアップは、完全に機能するSubversionリポジトリで、現行の リポジトリが何かひどいことになったときには、置き換えて使うことが できるものです。

両方のバックアップ方法にはそれぞれ利点があります。一番簡単なのは フルバックアップで、それは常に現行リポジトリの完全なコピーです。 繰り返しになりますが、何かまずいことが動作中のリポジトリに起きた 時には、単純な再帰的なディレクトリコピーでこのバックアップを 復元することができます。残念なことに、もしリポジトリの複数のバックアップ を管理している場合、このようなフルコピーは、実行中のリポジトリと 同じくらい、それぞれがディスクを食うということです。

リポジトリダンプ形式を使った差分バックアップはデータベーススキーマ が引き続くSubversion自身のバージョン間で変更されるときには非常に 役に立ちます。リポジトリの完全なダンプとロードは一般的に リポジトリを新しいスキーマにアップグレードすることが必要です。 そのような作業の半分(つまり、ダンプの部分)については既に 済んでいるのでとても便利です。不幸にも、差分バックアップの 作成—そしてそのリストア—は長い時間がかかりますが、 それは、それぞれのコミットがダンプファイル、またはリポジトリの 中で、実際に再実行されるからです。

どちらのバックアップの場合も、リポジトリ管理者は どのようにしてバージョン化されない属性への変更がバックアップに影響を 与えるかに注意する必要があります。このような変更は新しいリビジョンを それ自体で作り出すわけではないので、post-commitフックを呼び出すきっかけ にはならず、pre-revprop-chage や post-revprop-change フックのきっかけ にすらならないでしょう。 [19] そして、時間の順序に沿わないでリビジョン属性を変更することができる —いつでも、どのリビジョン属性を変更することができます— ので、最後のいくつかのリビジョンの差分バックアップはそれ以前の バックアップの一部として行われたリビジョン属性の修正は取り入れる ことができません。

一般的に言って、本当に人間離れした潔癖さを持った人だけが完全なリポジトリ のバックアップを必要とするのでしょう。つまり、コミットが起こるたびに バックアップをとるわけです。しかし、そのリポジトリが相対的に細かい 粒度(コミットごとのメールなど)と共に、何か別の冗長性の仕組みを持って いるのであれば、データベースのホットバックアップはリポジトリ管理者が システム全体の日次バックアップの一環として導入したいと考えるものかも知れません。 ほとんどのリポジトリでは、コミット メール をアーカイブするだけで復旧元 データとしての十分な冗長性を持っています。少なくとも最近のいくつかのコミット についてはそうです。しかしデータはとにかくあなたのものです— 必要なだけ保護するのに越したことはありません。

しばしば、リポジトリのバックアップに対する最良の方法は、分散 させることです。フルバックアップと差分バックアップに、コミット メールのアーカイブを追加することができます。たとえばSubversion 開発者は、Subversionソースコードリポジトリを、新しいリビジョン が作られるたびにバックアップします。そして、すべてのコミットと 属性変更の通知メールをアーカイブしてとっておきます。同様の方法を とってください。ただし、必要な範囲で、便利さと安全性の微妙なバラ ンスをとってください。そして、このようなことを全部やっても、運命 の鉄拳からハードウェアを守ることはできないことに注意してください。 [20] バックアップは確かにそのような試練の時からあなたを救うはずです。



[15] ところで、そのような設計は意図したものです。バグ ではありません。

[16] svnadmin dump は先頭スラッシュに関して一貫した ポリシーがありますが— 付けないようにするというものです— データをダンプするほかのプログラムはそれほど一貫していません。

[17] たとえば: ハードディスク + 強い電磁場 = 破滅。

[18] Subversionのリポジトリダンプ形式は、RFC 822形式によく 似ていて、ほとんどのメール で利用されているのと同じ形式です。

[19] たとえばsvnadmin setlogは、 とにかくフックインターフェースを迂回するような方法で呼び出されるのでした。

[20] ご存知でしょうか— 彼女のすべての「きまぐれ」をあらわす集合名詞です。