svn repository をバックアップするスクリプト

昨日 svn を運用しているサーバのディスクに障害が発生して、昨日今日はその復旧作業でほとんど潰れてしまった。

  • 2枚差しのディスクのうち片方が動作不良になってサーバが固まってしまった。
  • 強制リブートしてみたが、OS起動時のログを見る限り、上手く認識していない模様。
  • 2枚差しディスクを lvm で1つの論理パーティションとして扱っているのだが、df -h してみた感じでは特に変化は見られない。
  • ただ、動作がアヤシイのでこのまま使い続けるのは危険と判断し、故障したディスクを切り離す作業を行う。
  • とりあえず svnadmin hotcopy したリポジトリを別サーバにバックアップ。
  • 切り離し作業中に、resize2fs するまえに lvreduce してしまうという致命的ミスをやらかす。
  • lvextend して再度 e2fsck するも、ディスク容量がでかすぎ&サーバのスペック不足で、いつまでたっても終わらず。
  • 結合テスト環境の CentOS にて svn サービスを再開しようと試みるも、svn のバージョン違いでリポジトリバージョンが変わっており、うまいことアクセスできず。


という感じ。
結局、会社にあまってた別マシンに OS をクリーンインストールしてリポジトリごと移行という復旧手段となりました。


以下は、新環境にて作成した daily の svn バックアップスクリプト。ついかっとなって python で書いた。

#!/usr/bin/env python
import os
import popen2
import datetime

SVNROOT = '/var/www/svn'
BACKUPROOT = '/backup'

def dobackup(abspath):
    if not issvnrepos(abspath):
        return
    destrepos = os.path.join(getdestdir(), os.path.split(abspath)[1])
    command = '/usr/bin/svnadmin hotcopy %(abspath)s %(destrepos)s' % locals()

    stdout_and_err, stdin = popen2.popen4(command)
    for line in stdout_and_err:
        print line,

def issvnrepos(abspath):
    formatpath = os.path.join(abspath, 'format')
    if not os.path.isfile(formatpath):
        return False
    return True

def getdestdir():
    d = datetime.date.today().isoformat()
    dest = os.path.join(BACKUPROOT, d)
    if not os.path.isdir(dest):
        os.mkdir(dest)
    return dest

def main():
    for entry in os.listdir(SVNROOT):
        dobackup(os.path.join(SVNROOT, entry))

if __name__ == '__main__': main()