読者です 読者をやめる 読者になる 読者になる

GitBucketのDBが壊れたので直した

Tomcatのプロセスが予期せず終了したのが原因でGitBucketのデータベースが壊れた.
状況としてはこの記事と同じ.

rela1470.hatenablog.jp

この記事では最後に

$ mv data.mv.db data.h2.db

をしているが,それをしなければ一応は動くはず.
ただ,READ_CLOB_DBがある行を全て削除しているので,SSHキーの設定などが消えてしまう.ここをなんとかしたのでそのメモ.


まず,data.*.dbを保存しているディレクトリに移動後,

$ java -cp h2-1.4.180.jar org.h2.tools.Recover

でリカバリー用スクリプトを生成.
data.*.dbはバックアップを取っておく.

data.h2.sqlが生成される.
次に,data.h2.sqlからREAD_CLOB_DB関数のみ抽出し,

CREATE ALIAS IF NOT EXISTS READ_CLOB_DB FOR "org.h2.tools.Recover.readClobDb";
CREATE TABLE TMP(C0 VARCHAR, C1 VARCHAR);
INSERT INTO TMP VALUES('READ_CLOB_DB(1, 413)', STRINGENCODE(READ_CLOB_DB(1, 413)));
 ︙

と書き並べたsqlファイルを生成する.(create_tmp.sqlとする)
DBが壊れているとエラーで落ちるので,エラーが出た行はコメントアウトしておく.

data.*.dbを残したまま,これを実行.

$ java -cp h2-1.4.180.jar org.h2.tools.RunScript -url jdbc:h2:./data -user sa -password sa -script create_tmp.sql -showResults

select文を実行してファイルに保存.

$ java -cp ..\h2-1.4.180.jar org.h2.tools.Shell -url jdbc:h2:./data -user sa -password sa > from.txt
SELECT C0 FROM TMP;
exit;
$ java -cp ..\h2-1.4.180.jar org.h2.tools.Shell -url jdbc:h2:./data -user sa -password sa > to.txt
SELECT C1 FROM TMP;
exit;

java ~」の行を実行した後は標準出力をファイルにリダイレクトしてるので何も表示されないが,気にせず次の行を入力して大丈夫.
from.txt, to.txtの冒頭と末尾の余計な出力は削除して,以下のJavaのソースをコンパイルして実行
gist.github.com

data.*.dbを削除し,生成されたrecovery.sqlの中に含まれるREAD_CLOB_DBが出現する行を削除し実行

$ rm -rf data.h2.db data.trace.db
$ java -cp h2-1.4.180.jar org.h2.tools.RunScript -url jdbc:h2:./data -user sa -password sa -script recovery.sql -showResults

これでうまくいった.
本当は全て自動化したかったけど,試し試しやっていた上に気力が尽きたので,他の人に任せます.