1つだけ過去を変えられるとしたら?

実運用中のテーブルに対し、日次で reindex を実行したところ、時々、デッドロックが発生してしまいます。
どうやら、reindex と update の間でデッドロックが起きているようです。

エラーメッセージを見た感じでは、以下の状態でデッドロックになっているように読めます。
・update がテーブルのインデックスに対するロックを取得し、テーブルに対する RowExclusiveLock を取得しようとしている
・reindex がテーブルに対するロックを取得し、テーブルのインデックスに対する AccessExclusiveLock を取得しようとしている

※ 参考までに、update は select for update してから update しています。

Postgre のバグではないかと思うのですが、デッドロックを回避する方法はありますでしょうか?
(なるだけ、reindex を実行しているプロセスの方に手を入れることで対応できないかと思っています。例えば、reindexの前に事前にロックを取得する、とか・・・)

よろしくお願い致します。

A 回答 (1件)

REINDEXをテーブルごとに行っているならば、以下の手順でデッドロックは回避できます。



BEGIN;
LOCK tbl IN ACCESS EXCLUSIVE MODE;
REINDEX TABLE tbl;
COMMIT;

ただ、REINDEX中は参照も更新も待たされるため、基本的には、オンライン処理と並行しては実行できません。代わりに CREATE INDEX CONCURRENTLY + 古いインデックスを DROP INDEX というような運用を行うことはよくあります。

参考URL:http://www.postgresql.jp/document/current/html/s …
    • good
    • 0
この回答へのお礼

ご回答、有り難うございます。

私も、検証環境で現象を再現した上で、同様の変更(私の場合は EXCLUSIVE MODE を使いました)を試みたところ、デッドロックは出なくなりました。

CREATE INDEX CONCURRENTLY については、別な問題があるようですので、採用していません。
対象のテーブルがバッチ制御用のテーブルで、一時的に参照がブロックされても直接オンライン処理に影響が出ないため、REINDEX を使っています。

なお、質問時に書き忘れたのですが、参考までに環境について記載します。

vl60_cmn=# SELECT version();
version
-----------------------------------------------------------------------------------------------------------
PostgreSQL 8.3.1 on x86_64-unknown-linux-gnu, compiled by GCC gcc (GCC) 4.1.2 20070626 (Red Hat 4.1.2-14)
(1 row)

OSは CentOS 5 を使っています。

お礼日時:2011/04/23 13:28

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

関連するカテゴリからQ&Aを探す