ホームサーバーでハードドライブの障害が発生しました。
ディスクが正常に動作していることに気付いたら、ログインして、複数のプロジェクトを含むリポジトリのコピーを作成しました。
ただし、ディスクに障害が発生したため、リビジョンの1つが壊れています。
$ svnadmin verify master/
[...]
* Verified revision 820.
* Verified revision 821.
* Verified revision 822.
svnadmin: No such revision 823
master/db/revs/
およびmaster/db/revprops/
ディレクトリには、実際には823
というファイルが含まれていないため、このリビジョンはありません(壊れています)。リビジョン#947までのmaster/
リポジトリには、後続のリビジョン(本当に保持したい!)があります。
今日、最新のオフサイトバックアップ(!)を取得しました。これには、このリビジョンが含まれています。バックアップよりも新しいため、欠落しているリビジョンを修正することにより、master/
内の破損したリポジトリを「修復」したいと考えています。
master/
にコピーされたものと同じバージョンで新しく作成されたリポジトリにダンプファイルをロードすることを確認したので、それはすべて古い「線形」形式3です。
バックアップの823
およびdb/revs/
ディレクトリからファイルdb/revprops/
をコピーするだけで、明らかなことを試みました。
$ cp repos/db/revs/0/823 master/db/revs/
$ cp repos/db/revprops/0/823 master/db/revprops/
ディレクトリrepos/
には、バックアップダンプからロードされたリポジトリが含まれています。今私は得る:
$ svnadmin verify master/
[...]
* Verified revision 821.
* Verified revision 822.
svnadmin: /build/buildd/Subversion-1.6.12dfsg/Subversion/libsvn_delta/compose_delta.c:165: search_offset_index: Assertion `offset < ndx->offs[ndx->length]' failed.
Aborted
これはあまり励みになりません。他のさまざまなsvnadmin
コマンドを試しましたが、検証者を満足させるものはありません。
私の次のアイデアは、コピーをバックアウトし、壊れたリポジトリの「新鮮な」コピーから開始し、リビジョンafter823をダンプし、マージすることでしたバックアップ付き。しかし、それは不可能だと思われます。行方不明のリビジョンをダンプすることはできません。
$ svnadmin dump -r 824 master/ >r824.dmp
svnadmin: No such revision 823
ダンプが「インクリメンタル」になるのは、リビジョン824で始まった世界のふりをして、そこから先に進むことを期待していることに注意してください。
$ svnadmin dump --incremental -r 824:947 master/ > dump.txt
svnadmin: No such revision 823
これはdump.txt
に出力を書き込みますが、信頼できるかどうかはわかりません。正常にダンプされたanyリビジョンはログに記録されないことに注意してください。
更新:別のアイデアがありました:master/
のクラッシュディスクコピーから新しいリビジョンファイルをバックアップにコピーして、「失われたテール」を提供します。
$ for a in $(seq 910 947) ; do cp master/db/revs/$a repos/db/revs ; cp master/db/revprops/$a repos/db/revprops/ ; echo $a ; done
ただし、これはターゲットリポジトリを破損するだけです。
$ svnadmin verify repos/
[...]
* Verified revision 907.
* Verified revision 908.
* Verified revision 909.
svnadmin: Corrupt representation '907 21815 45 30922 158d3e72732f45bf6f02919b22fc899a'
svnadmin: Malformed representation header
今、私はアイデアを使い果たしました。
解決しました。
解決策は、(もちろん)気づいたら明白でした。
私はこれを持っていました:
master/
:破損したリポジトリのコピー。リビジョン0..947が含まれ、リビジョン823のファイルは物理的に欠落しています。repos/
:リビジョン0..910をカバーするバックアップ(ダンプファイル)からロードされたリポジトリ。解決策は、単にmaster/
、リビジョン911以降。これはエラーなしで可能でした。つまり、911..947の範囲のリビジョンはいずれも、リビジョン823の状態に直接依存していないことを意味します。
$ svnadmin dump --incremental -r 911:947 master/ > tail.txt
* Dumped revision 911.
* Dumped revision 912.
* Dumped revision 913.
[...]
* Dumped revision 947.
とにかく、バックアップからのリポジトリにダンプを適用するだけです:
$ cat tail.txt | svnadmin load repos/
[lots of commits]
そして今、私は完全な履歴が復元され、問題はありません:
$ svnadmin verify repos/
* Verified revision 0.
* Verified revision 1.
* Verified revision 2.
[...]
* Verified revision 945.
* Verified revision 946.
* Verified revision 947.
わーい!