概要
Git全盛のなか、頑なにSVNで運用を続けている企業も未だ多いことと思います。
サーバー老朽化などで、現行サーバーから新サーバーにノンストップで引っ越しを行なった際のあれこれをメモとして記録しておきます。
現行サーバーからのデータ取り出し
svnadmin dump リポジトリのパス > 出力するダンプのパス
生成したsvndumpファイルを新サーバーに転送しやすいよう、gzipで圧縮するようにしていましたが、オンプレ環境であれば、圧縮+転送する時間よりも、無圧縮のまま転送したほうが時間が短いことがわかった。複数リポジトリをまとめてダンプするシェルは以下
#!/bin/bash
reposArray=("repos1" "repos2" "repos3")
for repos in ${reposArray[@]}
do
svnadmin dump /path/${repos} > /path/${repos}.svndump
done
新サーバーでのデータ受け取りとデータの復元方法
ダンプしたファイルパスがわかっているので、winscpを使ってファイルのやり取りをするよりも、新サーバー上で、scpコマンドを使ってファイル転送をしたほうが効率的です。新サーバにログインしてファイルを保存する場所まで移動したら、以下の書式でコマンドを実行します。
scp 現行サーバーのユーザ@現行サーバー:リポジトリのパス .(カレンとディレクトリ)
とすればOK。実行時、パスワードを求められたら、現行サーバーのユーザのパスワードを入力。
scp User123@svn.localdomain .
ダンプデータを取り出して格納する先の空のリポジトリが必要なので、リポジトリを設置する予定の場所に移動してまずは新規作成します。
cd /path/svn/repos/
svnadmin create repos1
今回はダンプファイルがユーザーのホームディレクトリ直下にあると想定すると、loadは次のようになります。
svnadmin load -M 0 /path/svn/repos/repos1 < ~/repos1.svndump
「-M 0」のオプションがとても大事。
これがないと次のようなハッシュ値エラーが発生してロード途中で終了してしまうが、このオプションをつけることで回避。オプションの意味はよくわからないので、気になる方はこのページじっくり読んでください。
<<< オリジナルのリビジョン 10325 に基づき、新しいトランザクションを開始しました
* パスを編集しています : trunk/なんとか.csv ... 完了しました。
svnadmin: E160000: SHA1 of reps '-1 0 120 5431 b1da56934f4a2164f3900f0d3773317b a6921cb044298976482dd
0ff7bc1455862143776 10324-7ys/_b' and '-1 145 120 5431 b1da56934f4a2164f3900f0d3773317b a6921cb044298
976482dd0ff7bc1455862143776 10324-7ys/_b' matches (a6921cb044298976482dd0ff7bc1455862143776)
but contents differ
* パスを編集しています : trunk/なんとか.csv ...
新サーバーで現行サーバーとの差分データをsvnsyncで埋める
現行サーバーのSVNサーバーの運用を止めているわけではないので、ダンプ取得後もデータがコミットされ続けて新サーバーとの差分がどんどん増えていっています。リビジョン範囲を指定してダンプ取得、ロードという方法もありますが、svnsyncが使えるように設定したほうが、差分だけを新サーバーに取り込め、リビジョン番号などを気にしなくてもよいので都合がよいです。
事前準備としては各リポジトリでデータを受け取るために、フックスクリプト pre-revprop-changeを用意して、同期元・同期先サーバをsvnsync initコマンドを使って一度だけ実行することくらいです。
なおpre-revprop-change以外のフックスクリプトをカスタマイズしてると、例えばpre-commitなどで何かのエラーが出るかもしれませんが、pre-revprop-changeと同じ内容に一時的に書き換えてもらえれば処理は通るはず。
[pre-revprop-change]
#!/bin/sh
exit 0
chmod +x pre-revprop-change
リポジトリにデータが入っているときは、allow-non-empyオプションを付与しておかないとエラーとなるので注意
svnsync init http://localhost/repos1 http://svn.localdomain/repos1 --allow-non-empty
svnsync syncを定期的に実行。
svnsync sync http://localhost/repos1 \
--steal-lock \
--non-interactive \
--trust-server-cert \
--source-username=現行サーバのユーザ \
--source-password=現行サーバのパスワード \
--sync-username=新サーバのユーザ \
--sync-password=新サーバのパスワード
syncが失敗する場合などが稀にあり強制終了すると、–steal-lockを付与していないと、次回以降コマンドを発行した際に以下のようなエラーが発生する。
同期先リポジトリのロックを取得できませんでした
svnsync: E000022: Couldn't get lock on destination repos after 10 attempts
ロックを解除するには以下を実行する。
svn propdel svn:sync-lock --revprop -r 0 http://localhost/repos1
属性 'svn:sync-lock' をリポジトリのリビジョン 0 から削除しました
DNSサーバを切り替え
DNSでSVNサーバーのIPアドレスを変更して切り替えを完了させる。
コメント