[PostgreSQL]本当は怖いREINDEX
そしてSELECT文はたいていIndexを使用します。
つまり、たいていのケースではREINDEXでSELECT文がブロックされます。
(ブロックされないのは、そのテーブルにアクセスが全く来ない場合とか、よっぽど特殊なケース)
公式マニュアルにはこのことがはっきり書かれていない(極めて紛らわしい書き方になっている)ので注意が必要です。
REINDEXはインデックスの元となるテーブルの書き込みをロックしますが、読み込みはロックしません。この説明の肝は最後の一文にあります。
また、処理中のインデックスに対する排他ロックを取得するので、そのインデックスを使用する読み込みはブロックされます。
http://www.postgresql.jp/document/8.4/html/sql-reindex.html
たいていのSELECT文はインデックスを使用するので、「REINDEX中は読み込みブロックされる可能性が高い」と覚えておいた方が安全です。
ちなみに私は、「読み込みはロックしません」の意味を勘違いしてサービス稼働中にREINDEXしたら、サービス提供不能状態に陥ってしまいました。
公式MLの過去ログを見ると、私と同じように勘違いしてた人がいたようなので、一種のハマリポイントだと思われます。
どうすればよいか
サービス稼働中にIndexを再構築したい場合は、CREATE INDEX CONCURRENTLY というテクニックがあるのでこれを使いましょう。ただしこのテクニックはPRIMARY KEY Indexに対しては使えません。
PRIMARY KEY Indexを再構築したい場合は、サービスを停止してREINDEXするか、PostgreSQL 9.1でALTER TABLE ADD PRIMARY KEY USING INDEXを使うしかありません。
まとめ
サービス稼働中にIndex再構築したい
↓
それはPRIMARY KEY INDEXか? No → 「CREATE INDEX CONCURRENTLY&リネーム&削除」手法を使う
YES↓
PostgreSQL 9.1以上か? YES →「ALTER TABLE ADD PRIMARY KEY USING INDEX」手法を使う
No ↓
あきらめてサービス停止してREINDEX
カテゴリ:
PostgreSQL