はじめに
メンテナンスやサーバ移行で、Subversionで管理しているリポジトリすべてのバックアップを取得したい場合があると思います。
リポジトリ自体のバックアップ作成方法はマニュアルや参考となるブログが多く存在しますが、Windows上ですべてのリポジトリを対象にしようとすると、バッチ(スクリプト)を作成するのが一般的かと思います。
ただし、コマンドプロンプト用のバッチファイルは文字列加工などが不得意なので、今回はPowerShellを使ってスクリプトを作成しています。
既にPowerShell自体はWindowsServer標準となっているので、ほとんどの環境で利用が可能かと思いますが、どうしてもバッチでなければいけないという場合は自力で読み替えてください。
前提条件
WindowsでVisual Subversionを使って検証しています。
スクリプト
# 使用例
# .\dump_repositories.ps1 "C:\Repositories" "z:"
# "C:\Repositories"以下にあるリポジトリを、"z:"(ネットワーク)ドライブにダンプする
# リポジトリが保存されているディレクトリ
$repo_dir = $Args[0]
# リポジトリのダンプを保存する先
# スクリプトの実行者はログインユーザーとなるので、ネットワークドライブを指定することも可能です
$dump_dir = $Args[1]
$repo_list = @(Get-ChildItem $repo_dir | Where-Object{$_.PSIsContainer} | Select-Object FullName, Name)
# svnadmin.exeのパスを設定。ここでは、32bitアプリのインストールディレクトリを環境変数を用いて取得し、
# それ以降のパスとjoinさせている
$svnadmin = Join-Path ${env:ProgramFiles(x86)} "VisualSVN Server\bin\svnadmin.exe"
foreach($repo in $repo_list)
{
#作成されるダンプファイル名 <リポジトリ名>.dump
$dump_file = $repo.Name + ".dump"
#作成されるダンプファイルのフルパス
$dump_path = Join-Path $dump_dir $dump_file
#svnadminに与える引数。空文字区切りで配列を結合しています
$arguments = [string]::Join(" ", @("dump", $repo.FullName))
#processの実行
#-RedirectStandardOutput ダンプの出力先ファイルは標準出力のリダイレクト先として指定します
#-Wait ダンプが終わるまで画面に処理を戻しません
Start-Process -FilePath $svnadmin -ArgumentList $arguments -RedirectStandardOutput $dump_path -Wait
}
使い方は、ほとんどコード内に書いてあるが、例えば"C:\Repositories"にあるリポジトリ全てを、"z:\RepoDumps"フォルダにダンプする場合は、スクリプト(dump_repositories.ps1)が保存されているフォルダに移動し、以下のコマンドをPowershellで実行すればよい。
.\dump_repositories.ps1 "C:\Repositories" "z:\RepoDumps"
注意点
リポジトリのファイルサイズがさほど大きくない場合でも、フルダンプを作成する場合には履歴のサイズに応じてダンプファイルが膨らんでしまう場合がある(うちで行った場合がまさにこのパターン)ので、ダンプ先の空き容量は、十分に大きなサイズを準備して行わないとエラーで終了してしまう可能性があります。
また、ダンプ元とダンプ先が同じドライブの場合はディスクI/Oがボトルネックとなって時間が余計にかかる可能性があるので、意図的に別のドライブを選択するように配慮しましょう。
同様に、ネットワークドライブを指定した場合にはネットワークの帯域や速度がボトルネックとなる可能性があります。場合によっては、外付けのストレージデバイスを利用したほうがいいケースもあります。
以上、なんちゃってサーバー管理者の私自身が悩まされた事象を老婆心ながら列挙してみました。