トップに戻る 最初に戻る 前に戻る 次へ進む
$Date: 2014-08-18 08:57:12 +0900 (2014/08/18 (月)) $
$Revision: 978 $

Subversionリポジトリのバックアップ [svn-backup-dumps.py の利用方法]

概要

svnadmin dump をラップして、容易にフルバックアップ、インクリメンタルバックアップを 行えるようにした svn-backup-dumps.pyというツールがあります。 このページでは、 svn-backup-dumps.py の利用方法を説明します。

svn-backup-dumps.py の特徴

サポートしている機能

svn-backup-dumps.py では、以下の3つのタイプのバックアップをサポートしています。
  1. フルバックアップ
  2. リビジョンごとのバックアップ
  3. 複数リビジョンの差分バックアップ

動作原理

このスクリプトは 適切なコマンドライン引数を渡して、svnadmin dump を呼び出すだけの ラッパースクリプトです。Python binding は不要です。

入手先

対象環境

svn-backup-dumps.py は Windows, Unix 系OS のどちらでも使えます。

cron や post-commit から呼び出す場合、svnadmin へのパスを通す必要があります。
cron から呼び出す場合、こちら を参照。

バックアップの注意事項

svn-backup-dumps.py は svnadmin dump を使用してバックアップします。 svnadmin dump でバックアップする場合に注意事項があります。

バックアップを使用して復旧する状況としては、ハードディスクが 壊れて復旧したいという場合などが考えられます。しかしその状況では ダンプファイル自体が壊れている可能性があります。svnadmin load のときに ダンプファイルに対するエラーチェックが行われます。このときにエラーが 検出されてしまうと正常にリポジトリを復旧することができなくなります。

このような事態をさけるために、バックアップに冗長性を持たせるようにしましょう。 つまり、特定のリビジョンに対するバックアップが複数存在するようにしましょう。

例えば最新リビジョンが 120 のリポジトリがあるとした場合、フルダンプを取って おけば、OK のはずです。しかしこのダンプファイルの r50 のところにエラーが あったとすると r1 〜 r49 までは復旧できますが、r50 以降は復旧することが できなくなります。しかし、r50 〜 r120 の範囲を(リビジョンごとの)差分 バックアップしておけばその範囲のデータを救うことができます。

svn-backup-dumps.py の利用方法

ヘルプ

--help をつけて実行するとヘルプが表示されます。
C:\>svn-backup-dumps.py --help
Usage: svn-backup-dumps.py [options] repospath dumpdir

Options:
  --version        show program's version number and exit
  -h, --help       show this help message and exit
  -b               compress the dump using bzip2.
  --deltas         pass --deltas to svnadmin dump.
  -c CNT           count of revisions per dumpfile. ← 指定すると "3. 複数リビジョンの差分バックアップ"になる
  -o               overwrite files.
  -O               overwrite all files.
  -q               quiet.
  -r REV           revision number for single rev dump. ← 指定すると "2. リビジョンごとのバックアップ"になる
  -t TRANSFER      transfer dumps to another machine (s.a. --help-transfer).
  -z               compress the dump using gzip.
  --help-transfer  shows detailed help for the transfer option.

svn-backup-dumps.py を利用したバックアップ

svn-backup-dumps.py は以下の3つの方法でバックアップができます。 FTP や Windows の共有フォルダにバックアップする機能もありますが、 本質的には同じです。
  1. フルダンプ(フルバックアップ)

    タスクスケジューラ(Windows) や cron (Unix系OS) でバックアップするのに向いています。 この方法は比較的長い時間間隔(例: 1週間に一度)で行うことが想定されます。 もちろんデータが少ない場合はもっと頻繁に行っても大丈夫です。

    例(フルバックアップ)

    svn-backup-dumps.py svnrepos backupdir
    

  2. リビジョンごとのバックアップ

    post-commit フックスクリプトからのバックアップに向いています。 新たにコミットされるたびに、その分の差分バックアップを行います。

    例(リビジョン 101 をバックアップ)

    svn-backup-dumps.py -r 101 svnrepos backupdir
    

  3. 複数リビジョンの差分バックアップ

    タスクスケジューラ(Windows) や cron (Unix系OS) でバックアップするのに向いています。 この方法は比較的短い時間間隔(例: 1日に一度)で行うことが想定される。 データが少ない場合、フルダンプでも構わない。 一定時間ごとに、更新された分の差分バックアップを行うことを想定しています。

    例(リビジョン 50 個ずつバックアップ)

    svn-backup-dumps.py -c 50 svnrepos backupdir
    

フルダンプ(フルバックアップ) [svn-backup-dumps.py]

svn-backup-dumps.py <repos> <dumpdir>
c:\...\svnparent> mkdir backup  ← スクリプト実行前にディレクトリを作成しておく
c:\...\svnparent> svn-backup-dumps.py svnrepos backupdir
writing backupdir/svnrepos.000000-000094.svndmp
* リビジョン 0 をダンプしました。
* リビジョン 1 をダンプしました。
* リビジョン 2 をダンプしました。
* リビジョン 3 をダンプしました。
* リビジョン 4 をダンプしました。
                ...
* リビジョン 93 をダンプしました。
* リビジョン 94 をダンプしました。
Everything OK.

c:\...\svnparent> svn-backup-dumps.py svnrepos backupdir
backupdir/svnrepos.000000-000094.svndmp already exists. ← 既にファイルが存在する場合何もしない
Everything OK.

インクリメンタルダンプ(インクリメンタルバックアップ) [svn-backup-dumps.py]

svn-backup-dumps.py -r <revnrs> <repos> <dumpdir>
c:\...\svnparent> svn-backup-dumps.py -r 94 svnrepos backupdir
writing backupdir/svnrepos.000094.svndmp
* リビジョン 94 をダンプしました。
Everything OK.

c:\...\svnparent> svn-backup-dumps.py -r 94 svnrepos backupdir
backupdir/svnrepos.000094.svndmp already exists. ← 既にファイルが存在する場合何もしない
Everything OK.

複数リビジョンでのインクリメンタルバックアップ [svn-backup-dumps.py]

svn-backup-dumps.py -c <count> <repos> <dumpdir>
フルバックアップとインクリメンタルバックアップの中間的な方法です。 -c で指定したリビジョンに満たないリビジョンでもバックアップされます。 -c で指定したリビジョンの境界を意識する必要はありません。

具体例1 (-c オプションを使う場合)

シナリオ

  1. リビジョン45 で "-c 10" でバックアップを行う。
  2. リビジョン48 までリビジョンが進む
  3. リビジョン48 で "-c 10" でバックアップを行う。
  4. リビジョン54 までリビジョンが進む
  5. リビジョン54 で "-c 10" でバックアップを行う。

生成されるファイル

  1. リビジョン45 で "-c 10" でバックアップを行う。
    svnrepos.000000-000009.svndmp.bz2 ← リビジョン10 ずつバックアップされる。
    svnrepos.000010-000019.svndmp.bz2
    svnrepos.000020-000029.svndmp.bz2
    svnrepos.000030-000039.svndmp.bz2
    svnrepos.000040-000045.svndmp.bz2 ← -c の引数のリビジョンに満たないものもバックアップされる。
    
  2. リビジョン48 までリビジョンが進む
  3. リビジョン48 で "-c 10" でバックアップを行う。
    svnrepos.000000-000009.svndmp.bz2
    svnrepos.000010-000019.svndmp.bz2
    svnrepos.000020-000029.svndmp.bz2
    svnrepos.000030-000039.svndmp.bz2
    svnrepos.000040-000045.svndmp.bz2 ← 不要だけど自動的に消さない。でもディスク容量が許すかぎり残しておきたい
    svnrepos.000040-000048.svndmp.bz2 ← 新たに作成されるファイル
    
  4. リビジョン54 までリビジョンが進む
  5. リビジョン54 で "-c 10" でバックアップを行う。
    svnrepos.000000-000009.svndmp.bz2
    svnrepos.000010-000019.svndmp.bz2
    svnrepos.000020-000029.svndmp.bz2
    svnrepos.000030-000039.svndmp.bz2
    svnrepos.000040-000045.svndmp.bz2 ← 不要だけど自動的に消さない。でもディスク容量が許すかぎり残しておきたい
    svnrepos.000040-000048.svndmp.bz2 ← 不要だけど自動的に消さない。でもディスク容量が許すかぎり残しておきたい
    svnrepos.000040-000049.svndmp.bz2 ← 新たに作成されるファイル
    svnrepos.000050-000054.svndmp.bz2 ← 新たに作成されるファイル
    

具体例2 (-c と -b オプションを使う場合)

シナリオ

  1. リビジョン94 で "-c 10" でバックアップを行う。
  2. リビジョン99 までリビジョンが進む
  3. リビジョン99 で "-c 10" でバックアップを行う。

実行例

c:\...\svnparent> svn-backup-dumps.py -b -c 10 svnrepos backupdir
writing backupdir/svnrepos.000080-000089.svndmp.bz2
* リビジョン 80 をダンプしました。
* リビジョン 81 をダンプしました。
			...
* リビジョン 89 をダンプしました。
writing backupdir/svnrepos.000070-000079.svndmp.bz2
警告: リビジョン 69 のデータを参照していますが、これは、ダンプされた最も古い
警告: リビジョン (70 ) よりも古いものです。このダンプを空のリポジトリにロード
警告: する操作は失敗するでしょう。← r70 でタグへのコピーを行っています。
                                  このため r70 は r69 がないと失敗するということです。
                                  svnadmin dump -r 70 svnrepos としても同じ警告が出ます。
                                  参照
* リビジョン 70 をダンプしました。
* リビジョン 71 をダンプしました。
			...
* リビジョン 79 をダンプしました。

			...

writing backupdir/svnrepos.000020-000029.svndmp.bz2
* リビジョン 20 をダンプしました。
* リビジョン 21 をダンプしました。
			...
* リビジョン 29 をダンプしました。
writing backupdir/svnrepos.000010-000019.svndmp.bz2
* リビジョン 10 をダンプしました。
* リビジョン 11 をダンプしました。
			...
* リビジョン 19 をダンプしました。
writing backupdir/svnrepos.000000-000009.svndmp.bz2
* リビジョン 0 をダンプしました。
* リビジョン 1 をダンプしました。
			...
* リビジョン 9 をダンプしました。
writing backupdir/svnrepos.000090-000094.svndmp.bz2
* リビジョン 90 をダンプしました。
* リビジョン 91 をダンプしました。
			...
* リビジョン 93 をダンプしました。
* リビジョン 94 をダンプしました。
Everything OK.
その後、r99 まで進んでから再度実行した場合
c:\...\svnparent> svn-backup-dumps.py -b -c 10 svnrepos backupdir
writing backupdir/svnrepos.000090-000099.svndmp.bz2 ← r90 〜 r99 のみ更新される
* リビジョン 90 をダンプしました。
* リビジョン 91 をダンプしました。
* リビジョン 92 をダンプしました。
* リビジョン 93 をダンプしました。
* リビジョン 94 をダンプしました。
* リビジョン 95 をダンプしました。
			...
* リビジョン 98 をダンプしました。
* リビジョン 99 をダンプしました。
Everything OK.

バックアップデータの復旧 (bzip2圧縮している場合)

準備

復旧手順

例1: フルダンプからの復旧
c:\...\svnparent> svnadmin create svnrepos
c:\...\svnparent> bzip2 -c -d backupdir/svnrepos.000000-000099.svndmp.bz2 | svnadmin load svnrepos
例2: フルダンプ + 単一リビジョンのダンプからの復旧
c:\...\svnparent> svnadmin create svnrepos
c:\...\svnparent> bzip2 -c -d backupdir/svnrepos.000000-000090.svndmp.bz2 | svnadmin load svnrepos
c:\...\svnparent> bzip2 -c -d backupdir/svnrepos.000091.svndmp.bz2 | svnadmin load svnrepos
c:\...\svnparent> bzip2 -c -d backupdir/svnrepos.000092.svndmp.bz2 | svnadmin load svnrepos
                                          ...
c:\...\svnparent> bzip2 -c -d backupdir/svnrepos.000099.svndmp.bz2 | svnadmin load svnrepos
例3: 複数リビジョンの差分バックアップからの復旧
c:\...\svnparent> svnadmin create svnrepos
c:\...\svnparent> bzip2 -c -d backupdir/svnrepos.000000-000009.svndmp.bz2 | svnadmin load svnrepos
c:\...\svnparent> bzip2 -c -d backupdir/svnrepos.000010-000019.svndmp.bz2 | svnadmin load svnrepos
c:\...\svnparent> bzip2 -c -d backupdir/svnrepos.000020-000029.svndmp.bz2 | svnadmin load svnrepos
                                          ...
c:\...\svnparent> bzip2 -c -d backupdir/svnrepos.000090-000099.svndmp.bz2 | svnadmin load svnrepos

インクリメンタルダンプの警告

--incremental オプションをつけてダンプを取った場合、以下のような警告が 出ることがありますが、無害です。

英語

WARNING: Referencing data in revision 69, which is older than the oldest
WARNING: dumped revision (70).  Loading this dump into an empty repository
WARNING: will fail.
日本語
警告: リビジョン 69 のデータを参照していますが、これは、ダンプされた最も古い
警告: リビジョン (70 ) よりも古いものです。このダンプを空のリポジトリにロード
警告: する操作は失敗するでしょう。

例えば、r70 でタグ付けを行うために svn cp を行っている場合に r69 を含まないリビジョン範囲に対して svnadmin dump を行うと 表示される警告です。

svnadmin dump --incremental --revision 70:79 svnrepos ← r69 が含まれない

--incremental を指定してダンプした場合、指定リビジョンで更新された ファイル以外はダンプに含まれません。タグ付けのために svn cp を やっただけだと r69 の trunk を tags 以下にコピーするという情報が 入っているだけで、実際のデータはダンプファイルに含まれません。

このため空のリポジトリ(正確にはこの場合、r69 を含まないリポジトリ) に svnadmin load を実行した場合 r69 のデータが含まれないので、処理が 失敗するという意味の警告です。(至極当たり前です。)