第5章 リポジトリの管理

目次

リポジトリの基礎
トランザクションとリビジョンの理解
バージョン化されない属性
リポジトリの保存形式
リポジトリの作成と設定
フックスクリプト
Berkeley DB の設定
リポジトリの保守
管理者用ツールキット
リポジトリのお掃除
ディスク領域の管理
リポジトリの復旧
リポジトリの移行
リポジトリのバックアップ
プロジェクトの追加
リポジトリレイアウトの選択
レイアウトの作成と、初期データのインポート
まとめ

Subversionのリポジトリは複数のプロジェクトのためのバージョン管理 されたデータを格納する中心的な場所です。こんなわけで、リポジトリは 管理する人間にとってはたまらない魅力のある場所になるかも知れません。 リポジトリは一般的にはそれほど複雑な管理が必要なものではありません が、正しく設定し、潜在的な問題を避け、実際に起こる問題を安全に解決する ためにはどうすれば良いかを理解することは重要です。

この章では、Subversionのリポジトリをどうやって作成し設定するかについて 議論します。リポジトリ管理についても述べますが、 これには svnlooksvnadmin (この二つはSubversionが提供するツールです)の利用も含まれています。 よくある質問と間違いをとりあげ、リポジトリ中でどのようにデータを 配置するのか良いかについてアドバイスします。

もし、Subversionのリポジトリのバージョン管理下にあるデータに ユーザとしてアクセスするだけなら、(つまり、Subversionのクライアント としてだけ利用するなら)この章は読み飛ばすことができます。しかし、 Subversionのリポジトリ管理者か、そうなろうと思っている人は [13] この章に特別の注意を払ってください。

リポジトリの基礎

リポジトリ管理についての広範囲な話題に飛び込む前に、リポジト リとはいったい何であるかをもう少し突っ込んで定義しておきましょう。それ はどんな風に見えるのでしょうか? いったいどんなコなんでしょう? 飲み物の好みは? ホット? アイス? 砂糖はいくつ? レモンは? 管理者としては、論理的な見え方 —つまり、リポジトリ内でデータがどのように表現されているか— から物理的な細部に到るまで—つまり Subversion 以外のツールから リポジトリはどう見え、どう振舞うか—の両方について理解している ことが期待されます。以下の節は非常に高レベルの基本的な概念のいくつか について説明します。

トランザクションとリビジョンの理解

概念的に言うと、Subversionのリポジトリはディレクトリツリーの 並びです。それぞれのツリーはある時刻で、リポジトリ中に 管理されたファイルやディレクトリがどのように見えるか、という ことについてのスナップショットです。 このクライアントの操作によって作られるスナップショットを リビジョンといいます。

それぞれのリビジョンはトランザクションツリーとして生まれます。 コミットすると、クライアントは、自分のローカルな変更(と、クライアント のコミット処理の最初にリポジトリに起きる附加的な変更)を反映 したSubversionのトランザクションを作り、次のスナップショットとして このツリーを格納するようにリポジトリに命令します。 コミットが成功すれば、トランザクションは新しいリビジョンツリーが できたことを知らせ、新しいリビジョン番号を割り当てます。 コミットが何かの理由で失敗すれば、トランザクションは消されて、クライアント は失敗した旨の通知を受けます。

更新処理も同様に動作します。クライアントは作業コピー の状態を反映した一時的なトランザクションツリーを作ります。リポジトリは そのトランザクションツリーを要求されたリビジョンのツリー(普通は 最新の、あるいは「一番若い」ツリー)と比較し、作業コピーを リビジョンツリーの形に変形するにはどのような変更が必要であるかに ついての情報を戻します。更新が完了した後、その一時的なトランザクションは 削除されます。

トランザクションツリーの利用がリポジトリのバージョン管理された ファイルシステムに普遍的な変更を起こす唯一の方法です。しかし、 トランザクションの生存時間が完全に任意であることを理解するのは 重要です。更新の場合トランザクションはすぐに消滅する一時的なツリー です。コミットの場合は、トランザクションは普遍的なリビジョンに 変わります。(あるいはコミットが失敗したときは削除されますが) エラーやバグがあると、トランザクションはリポジトリの周辺に 取り残されてしまうかも知れません(しかしこれは領域を食うだけで、 何かに悪い影響を与えたりはしませんが)

理論的には、いつの日か、統合された作業環境をサポートする アプリケーションはトランザクションの生存期間をもっと柔軟に 管理することができるようになるかも知れません。 クライアントがリポジトリに対する修正内容の記述を終えたあとでも、 リビジョンになる候補のトランザクションが 静止した状態にとどまるようなシステムを考えることもできます。 これはそれぞれの新しいコミットを別の人、たとえば管理者やエンジニアの QAチームによって再検討することを可能にし、そのトランザクション を本当のリビジョンにしたり、取り下げたりすることができるようになるでしょう。

バージョン化されない属性

Subversionリポジトリでのトランザクションとリビジョンは 付随した属性を持つことができます。そのような属性は 一般的なキー・値のマッピングで、関連したツリーについての 情報を格納するのに一般的に利用されます。属性の名前と値はリポジトリの ファイルシステム中に、残りのツリーデータと一緒に格納されます。

リビジョンとトランザクションの属性はファイルやディレクトリ にそれほど強く結びついていないツリーの情報を記憶して おくのに便利です—作業コピーによって管理できないような 情報です。たとえば新しいコミットトランザクションが リポジトリに作られるとSubversionはそのトランザクションに svn:dateという名前の属性を追加します —トランザクションが作られた時刻を示すタイムスタンプです。 コミットが完了し、トランザクションが普遍的なリビジョンとなる 時点で、ツリーにはリビジョン作成者のユーザ名称(svn:author) とリビジョンに付けられたログメッセージ(svn:log)の 属性が追加されます。

リビジョンとトランザクションの属性は バージョン化されない属性です— 修正されると、それ以前の値は永久に失われてしまいます。 同様にリビジョンツリー自身は不変ですが、ツリーに付けられた 属性はそうではありません。いつでもリビジョン属性を追加、削除、修正 することができます。新しいリビジョンをコミットしたあとで、 間違った情報だったり、ログメッセージにスペルミスがあったり したことがわかったときには、単にsvn:log 属性の値を正しいログメッセージで置き換えてやるだけです。

リポジトリの保存形式

Subversion 1.1 からは、Subversion リポジトリに二つの保存形 式が選べます。一つはすべてのデータを Berkeley DB データベースに保存 する方法です; もう一つは、独自の形式で構成した通常のフラットファイルの 形にデータを保存する方法です。Subversion 開発者はリポジトリを、 「(バージョン化された) ファイルシステム」 という名前でよく言い表すので、 この習慣に合うように後者のリポジトリをFSFS [14] と呼びますが—それは最初から OS がもっているファイルシステムを使っ てバージョン化されたファイルシステムを作る方法です。

リポジトリを作成する時には、管理者は Berkeley DB を使うか、FSFS を使うかを決めなくてはなりません。両方とも、利点と欠点がありますが、そ れについては後で少し触れます。どちらか一方がもう一方よりも「公式 のもの」であるということはありませんし、リポジトリへのアクセスは これらの実装の詳細とは分離されています。プログラムはどうやって保存して いるデータにアクセスするかを知ることはありません; リポジトリ API 全体 を通じて、抽象化されたリビジョンとトランザクションツリーが見えるだけで す。

表 5.1. 「Repository 保存形式の比較」 に Berkeley DB と FSFS リポジトリの比較表があります。 詳細についてはは次の節を見てください。

表 5.1. Repository 保存形式の比較

機能Berkeley DBFSFS
リポジトリの壊れやすさ非常に壊れやすい; リポジトリが壊れたりパーミッショ ンの問題が起こった場合にはデータベースは「中途半 端な」状態になり、ジャーナル復帰処理が必要にな ります。それほどでもない
リードオンリーでマウントできるかいいえはい
プラットフォームに独立した保存形式かいいえはい
ネットワークファイルシステムでも使えるかいいえはい
リポジトリサイズわずかに大きいわずかに小さい
スケール性: リビジョンツリーの数が増えるとどうな るかデータベースなので問題なしOS のファイルシステムが古い場合、一つのディ レクトリ中に数千のエントリがあるとうまく動かなくなるこ とがある。
スケール性: たくさんのファイルのあるディレクトリ遅い速い
スピード: 最新コードのチェックアウト速い遅い
スピード: 大きなコミット遅いが、処理の負荷はコミット全体に分散する速いが、最終処理はクライアントのタイムアウトにつ ながるかも知れない
グループパーミッション制御umask の問題に敏感; ひとつのユーザによってアクセ スされるのが一番よい。umask の問題を回避できる
コードは枯れているか2001 年から使われている2004 年から使われている

Berkeley DB

Subversion の最初の 設計段階で、開発者はさまざまな理由で Berkeley DB を利用することに決めました。 その理由にはそのオープンソースライセンス、トランザクションのサポート、 信頼性、パフォーマンス、API の公開、スレッドの安全性、カーソルのサポート などが含まれていました。

Berkeley DB は本当のトランザクション機能をサポートしています—おそらく 上であげた理由の中で最も強力な機能です。Subversion リポジトリにアクセスする 複数のプロセスはそれぞれ他のデータを間違って破壊することを心配する必要はありません。 トランザクションシステムによって提供されている分離機能はどんな操作においても Subversion リポジトリのコードにデータベースを静的に見せることができるように するものです—他のプロセスによってときどき変更を受けているように見えるのを 防ぐものです— そしてそのような静的な見え方に基づいて、何を実行するか を決めることができるのです。もしその決定が他のプロセスがやったことと衝突 した場合、操作全体は、それがまったく実行されなかったかのようにロールバック され、Subversion はもう一度、新しく更新された(そしてやはりまた静的に見える ような状態での)データベースに対してその処理を再実行することができます。

Berkeley DB のほかのすばらしい機能はホットバックアップ — 「オフライン」にせずにデータベース環境をバックアップできる 能力です。リポジトリのバックアップ方法についてはリポジトリのバックアップ項で議論しますが、オフラインに せずにリポジトリの完全なコピーをとることができる利点は明白でしょう。

Berkeley DB はまた非常に信頼性の高いデータベースシステムです。Subversion は Berkeley DB のログ機能を利用しますが、これはまず最初にこれからやろうと する操作内容をいったんディスク上のログファイルに書き込み、それからその 修正を実際に行うものです。これは何かまずいことが起きた場合にデータベースシステム が直前のチェックポイント— ログファイル中の最後の 問題のない地点— をバックアップすることと、データが利用可能な 状態に復元されるまでトランザクションを再実行することを保証するものです。 Berkeley DB ログファイルについての詳細はディスク領域の管理項を 見てください。

しかしどんなバラにもトゲがあるわけであり、Berkeley DB についてわかっている 制約を記しておく必要があります。まず Berkeley DB 環境は可搬性がありません。 Unix システムで作った Subversion リポジトリをWindowsシステムに単にコピー して動作することを期待してはいけません。ほとんどの Berkeley DB データベース 形式はプラットフォーム独立ですが、環境中にはそうではない部分もあります。 次にSubversion では Berkeley DB を Windows 95/98 システム上で利用できません — ウィンドウズマシン上でリポジトリを管理しなくてはならない のであれば Windows 2000 か Windows XP 上に構築してください。また Berkeley DB リポジトリをネットワーク共有上には決して置かないでください。Berkeley DB は 仕様の一部に合致するようなネットワーク共有上での正しい動作を保証していますが、 現在実際に利用されているネットワーク共有方式で、そのすべての仕様を満たすよう なものは知られていません。

最後に、Berkeley DB は Subversion に直接リンクされたライブラリな ので典型的なリレーショナルデータベースよりも割り込みに関して敏感です。 例えばほとんどの SQL システムでは、テーブルに対するアクセス全体を取り持つサー バプロセスがあります。何かの理由でデータベースにアクセスするプログラム に異常があった場合でもデータベースデーモンは接続が中断したことを検知し て問題のある中間的な状態をきれいにします。またデータベースデーモンはテー ブルにアクセスする唯一のプロセスなのでアプリケーションはパーミッション の衝突に関して心配する必要はありません。このような性質は Berkeley DB にはありません。Subversion (と Subversion ライブラリを使うプログラム) はデータベーステーブルに直接アクセスしますが、これはプログラムで異常が あると、データベースが中間的な矛盾のある状態、アクセスできない状態のま ま残ってしまうことを意味します。このようなことがおこると、管理者は Berkeley DB に問い合わせてチェックポイントを回復する必要がありますが、 これは少し面倒な作業です。リポジトリが 「中途半端な」状態に なるのはプログラムの異常のほかにも、データベースファイルに対して与えら れたオーナーやパーミッションに関係することもあります。このように、 Berkeley DB は非常に速くスケール性にも富んでいますが、一つのサーバプロ セスを一つのユーザで実行する—たとえば Apache's httpdsvnserve (章 6. サーバの設定 を見てください。)— のが最善の利用 方法であり、file:///svn+ssh:// のような URL を使ってたくさん の異なるユーザがアクセスするのは避けたほうがよいでしょう。複数ユーザか ら直接 Berkeley DB をアクセスする場合には、かならず複数リポジトリアクセス方法のサポート項を読むようにしてください。

FSFS

2004年の半ばから、第二のリポジトリ保存形式が使えるようになりまし た: これはデータベースをまったく利用しないものです。FSFS リポジトリは リビジョンツリーを単一のファイルに保存し、すべてのリポジトリリビジョン は単一のサブディレクトリの下の複数ファイルになります。トランザクション は分離されたサブディレクトリに作られます。トランザクションが完了すると 単一のトランザクションファイルが作られ、それがリビジョンディレクトリに 移動されます。このためコミットの不分割性が保証されます。そして、リビジョ ンファイルは永続的なものであり、それ以上変更されないのでリポジトリは Berkeley DB リポジトリのように「ホット」バックアップするこ とができます。

リビジョンファイルの形式は、そのリビジョンのディレクトリ構造、ファ イル内容、そして他のリビジョンツリーのファイルに対する差分を表現したも のです。Berkeley DB データベースとは違いこの保存形式は異なるオペレーティ ングシステム間でもそのまま利用することができ、CPU のアーキテクチャには 依存しません。ジャーナリングのしくみや共有メモリーを使っていないので、 リポジトリはネットワークファイルシステムごしに安全にアクセスすることが でき、リードオンリーな環境を作ることもできます。またデータベース保存形式特 有のオーバーヘッドがないので、リポジトリの大きさは比較的小さくなります。

FSFS はパフォーマンスの特性にも独自の性質があります。非常にたく さんのファイルのあるディレクトリをコミットすると、FSFS は O(N) アルゴ リズムを使ってエントリーを追加しますが、Berkeley DB は O(N^2) のアルゴ リズムを使ってディレクトリ全体を書き換えます。いっぽう FSFS は以前の バージョンと、今回の最新バージョンのファイルの差分を書き込みます。 これは最新ツリーをチェックアウトする場合 Berkeley DB の HEAD リビジョンに保管されている完全な内容にアクセスするよりも少し遅くなる ことを意味しています。FSFS はコミットの最終処理でも相対的に長い遅延が 起こりますが、これは極端な場合には応答を待つ クライアントプログラムをタイムアウトさせてしまうかも知れません。

しかし一番大きな違いは FSFS では何かおかしなことが起こったときで も、「中途半端な」状態にはならないところです。Berkeley DB データベースを使ったプロセスがパーミッションの問題や突然異常終了したよ うな場合だと、データベースは管理者が復帰処理をしない限り利用できない状態に とどまります。もし同じことが FSFS リポジトリに起きても、リポジトリはまっ たく影響を受けません。せいぜいトランザクションデータが見えない場所に取 り残されてしまうだけです。

FSFS に対する唯一の問題は Berkeley DB に比較してそれほど枯れてい ないところです。 Berkeley DBほどの耐久性テストはされていないので、スピー ドとスケール性についてここで述べた多くの内容は: 妥当な推測に基づくもの です。理屈の上では FSFS は新しい管理者がとりかかる時の敷居を下げて、問 題の影響を受けにくくするはずです。実際にどうかは、いずれ時が答えてくれ るでしょう。



[13] こう書くと、なんだかとても高尚なことのように思えますが、 みんなのデータがある作業コピーの背後で起きている神秘の領域に 興味を持つ人なら、誰でも、という意味です。

[14] Jack Repenning が何も文句を言わないのなら「fuzz-fuzz」 と発音することになっています。