PostgreSQL復旧

8月11日のエントリで書いた件。この手順だとダメでした。当たり前か。
どうしてこんなことがおきたかというとですね。

  • 当該サーバ上ではPostgreSQL8.2.11をつかってデータベースが初期化、生成されていた。8.2.11は/usr/local/pgsql以下へインストールされている。
  • その中のあるDBをdropすることになったが、dropdbすると下記エラーが発生する。
DETAIL:  Could not open file "pg_clog/0008": No such file or directory.
  • clogのシーケンスをリセットすればいいかなとあまり深く考えないで一旦DBをシャットダウン。pg_resetxlogを実行。
$ pg_resetxlog -f /usr/local/pgsql/data
  • 上記でパスをつけないで実行したため、/usr/binにインストールされていた古いバージョンのpg_resetxlogが実行される。このpg_resetxlogのバージョンは8.1.11。
  • pg_resetxlogによって、data/global/pg_controlに自身のバージョンが書き込まれる。
  • そうすると、/usr/local以下へインストールされているpostmasterで起動しようとすると、8月11日のエントリに書いたようなエラーが発生する。
$ /usr/local/pgsql/bin/pg_ctl start
server starting
FATAL:  database files are incompatible with server
DETAIL:  The database cluster was initialized with PG_CONTROL_VERSION 812, but the server was compiled with PG_CONTROL_VERSION 822.
HINT:  It looks like you need to initdb.

ということみたいです。復旧には/usr/local/pgsql/bin以下に入っている8.2.11のpg_resetxlogを使用し、-xオプションをつけてさらにリセット。

$ /usr/local/pgsql/bin/pg_resetxlog -f  -x 0x2500000 /usr/local/pgsql/data/

"-x"で指定する数字は、復旧対象のpg_clogに存在するファイルの一番大きな数字に1を加えて000000をうしろにくっつけたもの。私が実行したときはpg_clogはこんな状態でした。

$ ls -l 
-rw-------   1 postgres postgres  262144  3月  1日  11:06 0020
-rw-------   1 postgres postgres  262144  3月 12日  09:11 0021
-rw-------   1 postgres postgres  262144  6月 12日  02:31 0022
-rw-------   1 postgres postgres  262144  7月 30日  13:23 0023
-rw-------   1 postgres postgres  147456  8月 11日  09:23 0024

よって"-x 0x2500000"を指定してリセット。無事に復旧できました。いやぁDB吹っ飛ばしたかとおもって冷や汗をかきました。