共有システムカタログのインデックス破損時のリカバリ
ついカッとなって、PostgreSQLの共有システムカタログのインデックスを壊してリカバリすることにしてみた。
マニュアルに一応、やり方は書いてあるのですが実際にやった人のブログ等ないので、やって見ます。
1.共有システムカタログ(今回は、pg_database)のインデックスのfilenodeを確認
testdb=# select relname , relfilenode from pg_class where relname like 'pg_database_%'; relname | relfilenode ---------------------------+------------- pg_database_datname_index | 2671 pg_database_oid_index | 2672
対象のインデックスのfilenodeは2671と2672であることが判明。
共有システムカタログは$PGDATA/global/以下に配置されている。
2.共有システムカタログのインデックスを壊して、DB再起動
[postgres@dbsvr ]$ echo " " > /usr/local/pgsql/data/global/2671 [postgres@dbsvr ]$ echo " " > /usr/local/pgsql/data/global/2672 [postgres@dbsvr ]$ pg_ctl restart waiting for server to shut down.... done server stopped server starting
壊したインデックスがキャッシュされているので、とりあえずDB再起動する。
3.インデックスが壊れたことを確認
[postgres@dbsvr ]$ psql -l psql: FATAL: could not read block 0 of relation 1664/0/2672: read only 2 of 8192 bytes [postgres@dbsvr ]$ psql testdb psql: FATAL: could not read block 0 of relation 1664/0/2672: read only 2 of 8192 bytes
データベースの一覧表示や作成したデータベースへの接続が出来ないことを確認。
4.システムインデックス未使用モードでリカバリを実施
[postgres@dbsvr ]$ export PGOPTIONS="-P" [postgres@dbsvr ]$ psql testdb Welcome to psql 8.3.5, the PostgreSQL interactive terminal. testdb=# reindex system testdb;
一見するとこれで、リカバリできそうな気もしますがマニュアルの記載どおりREINDEXは、マルチユーザモードでは共有カタログを処理しないようで華麗に壊したインデックスはスルーされました。
5.シングルユーザモードで再起動し、インデックスを再構築する
[postgres@dbsvr ]$ postgres --single testdb 2009-02-12 11:33:39 JST FATAL: could not read block 0 of relation 1664/0/2672: read only 2 of 8192 bytes [postgres@dbsvr ]$ postgres --single testdb -P PostgreSQL stand-alone backend 8.3.5 backend> reindex system testdb; [postgres@dbsvr ]$ pg_ctl start server starting
シングルユーザモードでも、"-P"オプションを付けてないと起動できないので注意。
無事起動できたら、システムインデックスを再構築し、通常モードで再度起動する。
これで、無事リカバリ完了。
実際のリカバリの手順としては、4は不要です。
ただし、共有システムカタログではなく、普通のシステムカタログ(pg_class等)の場合は、4の手順でリカバリ出来ます。
共有システムカタログ(pg_authid、pg_auth_members、pg_database、pg_pltemplate、pg_shdepend、pg_shdescription、pg_tablespace)と、
普通のシステムカタログでリカバリの方法が若干異なることを理解しておく必要がありますね。
でも、私は未だに普通のインデックスすら壊れた経験がないので、今後この障害に遭遇する可能性は少ないかもしれませんが
知ってると数分で復旧できるものが、知らないと数時間とか掛かりそうなので知っておくことに損はないとかと。