Posted at

h2 databaseをリカバリする

More than 3 years have passed since last update.

プロジェクトでGitBucketを半年以上運用しているのだけど、最近どうもh2(1.4系)の調子が悪い。

利用しているサーバのディスク容量が逼迫しているタイミングで以下のようなエラーが発生し、それ以降調子が悪くなっているように思える。

org.h2.jdbc.JdbcSQLException: 一般エラー: "java.lang.IllegalStateException: Corrupt page count -1107358 [1.4.180/3]"

org.h2.jdbc.JdbcSQLException: 一般エラー: "java.lang.IllegalStateException: Chunk 39556 not found [1.4.180/6]"

General error: "java.lang.IllegalStateException: Chunk 39556 not found [1.4.180/6]"; SQL statement:

あと、そんなに容量使っているはずが無いのにdata.mv.dbのサイズが突如8Gまで増えたので絶対なにかおかしい!ってことでリカバリを試みてみた。


準備


  • リカバリツール(というかh2)を以下からダウンロードする



リカバリツールはmv.dbに直接何かを行うわけではないけど、利用しているGitBucketを止め、data.mv.dbをバックアップしておく。

自分の場合は一旦ローカル環境に落としてきて作業を行った。


リカバリする

以下にh2のリカバリツールについて説明がある。

実行すると、mv.dbからDDLを吐いてくれる模様。

jarと同一ディレクトリ上にmv.dbファイルを配置してコマンドを実行すると

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

以下の2つのファイルが作成された。


  • data.mv.txt

  • data.h2.sql

$ ls -l

total 10462247
-rw-r--r-- 1 tenten0213 Domain Users 729039193 Apr 23 09:41 data.h2.sql
-rw-r--r-- 1 tenten0213 Domain Users 8669241344 Apr 22 22:54 data.mv.db
-rw-r--r-- 1 tenten0213 Domain Users 1313285792 Apr 23 09:40 data.mv.txt
-rw-r--r-- 1 tenten0213 Domain Users 98 Apr 23 09:18 h2.bat
-rwxr-xr-x 1 tenten0213 Domain Users 109 Apr 23 09:18 h2.sh
-rw-r--r-- 1 tenten0213 Domain Users 1763882 Apr 23 09:18 h2-1.4.191.jar
-rw-r--r-- 1 tenten0213 Domain Users 105 Apr 23 09:18 h2w.bat

data.mv.txtを見た感じ、mv.dbの構造を表したようなもの?に見える。

ファイルの末尾の方に以下の内容が出力されていて、日付がエラーが発生した日からだから怪しんでいる。(全然的外れかもしれないけど)

Last modified: 2016-04-22 22:54:22 (+12465916 s)

File length: 8669241344
The last chunk is not listed
Chunk length: 8111247360
Chunk count: 3906
Used space: 92%
Chunk fill rate: 7%
Chunk fill rate excluding empty chunks: 7%
Chunk 37480: 2016-04-11 09:09:12 (+11466006 s), 8% used, 404 blocks
Chunk 37525: 2016-04-11 09:46:13 (+11468227 s), 1% used, 640 blocks
Chunk 38259: 2016-04-11 17:00:25 (+11494279 s), 1% used, 947 blocks
Chunk 38586: 2016-04-11 18:57:34 (+11501308 s), 1% used, 907 blocks
Chunk 38854: 2016-04-12 11:12:28 (+11559802 s), 1% used, 919 blocks
Chunk 38898: 2016-04-12 11:29:44 (+11560838 s), 1% used, 919 blocks
Chunk 38904: 2016-04-12 11:30:28 (+11560882 s), 1% used, 935 blocks
Chunk 39422: 2016-04-12 18:23:31 (+11585665 s), 5% used, 372 blocks
Chunk 39544: 2016-04-13 07:47:20 (+11633894 s), 1% used, 444 blocks
Chunk 39580: 2016-04-13 07:47:34 (+11633908 s), 1% used, 536 blocks
Chunk 39618: 2016-04-13 07:49:11 (+11634005 s), 1% used, 612 blocks
Chunk 40065: 2016-04-13 08:06:18 (+11635033 s), 98% used, 627 blocks
Chunk 40066: 2016-04-13 08:06:19 (+11635033 s), 98% used, 686 blocks
Chunk 40067: 2016-04-13 08:06:19 (+11635033 s), 96% used, 687 blocks
Chunk 40068: 2016-04-13 08:06:19 (+11635033 s), 97% used, 684 blocks
Chunk 40071: 2016-04-13 08:06:19 (+11635033 s), 94% used, 78 blocks
:

出来上がったDDLを実行する。今度はtoolsのRunScriptを使う。

jdbcのURLは新規でDBを作りたい為dataではなくnewとしている。元のファイルを上書きしなければ任意の名前で良い。

$ java -cp h2-1.4.191.jar org.h2.tools.RunScript -url jdbc:h2:~/backup/h2/bin/new -user sa -password sa -script data.h2.sql -driver org.h2.Driver -showResults

new.mv.dbができている。data.mv.dbは8Gなのに450Mくらいしかない!(こっちが普通か)

$ ls -lh                                                                                                                                

total 11G
-rw-r--r-- 1 tenten0213 Domain Users 696M Apr 23 09:41 data.h2.sql
-rw-r--r-- 1 tenten0213 Domain Users 8.1G Apr 22 22:54 data.mv.db
-rw-r--r-- 1 tenten0213 Domain Users 1.3G Apr 23 09:40 data.mv.txt
-rw-r--r-- 1 tenten0213 Domain Users 2.3K Apr 23 10:42 data.trace.db
-rw-r--r-- 1 tenten0213 Domain Users 98 Apr 23 09:18 h2.bat
-rwxr-xr-x 1 tenten0213 Domain Users 109 Apr 23 09:18 h2.sh
-rw-r--r-- 1 tenten0213 Domain Users 1.7M Apr 23 09:18 h2-1.4.191.jar
-rw-r--r-- 1 tenten0213 Domain Users 105 Apr 23 09:18 h2w.bat
-rw-r--r-- 1 tenten0213 Domain Users 444M Apr 23 11:02 new.mv.db

あとは、サーバにあるdata.mv.dbを置き換えて起動すればOK.

最近イロイロあってh2辛かったけど、そろそろh2以外のDBの対応がGitBucketに入る模様なので期待して待っていたい。


GitBucket関連の他の記事