[pgpool-general-jp: 95] Re: VACUUM時のinsert_lockについて

Tatsuo Ishii ishii @ sraoss.co.jp
2007年 2月 21日 (水) 15:26:40 JST


石井です.

> 浅羽です。
> 
> From: "YOSHIDA Kaname" <kaname @ conga.jp>
> Subject: [pgpool-general-jp: 93] VACUUM時のinsert_lockについて
> Date: Wed, 21 Feb 2007 14:22:41 +0900
> 
> > 現在pgpool(pgpool-I)でload_balance_mode=true, replication_mode = true
> > で使用しております。また、replication_strict = true, insert_lock = trueの
> > 設定になっています。
> > 
> > VACUUM時にSHARE UPDATE EXCLUSIVEのロックがかかりますが、
> > これとinsert_lockのかけるSHARE ROW EXCLUSIVEが衝突して
> > VACUUM中にINSERTができません。
> > (VACUUMは、pgpool経由ではなくそれぞれのpostgresqlで実行しています)
> > 
> > insert_lockでテーブルをロックするのは、シーケンスがずれないように一つの
> > トランザクションのみにINSERTを限定するのが理由だと理解しましたが
> > 合っていますでしょうか?
> 
> はい、そうです。INSERT は新しい行を挿入するので行ロックという概念が無
> いため、テーブルをロックしてトランザクションを直列にしています。
> 
> 
> > もしそのような理由だとすれば、対象のテーブル自身にロックをかける必要はなく、
> > テーブル毎に共通のロック用テーブルを用意してそれを排他制御のフラグとして
> > 利用すればいいのではないかと考えました。
> > 
> > 以下のパッチのように、ロックをかけるのはロック用のテーブルにして、
> > 各テーブル(ex: tablename)にロック用のテーブル(ex: lock_tablename)を用意しました。
> > 
> > --- pool_process_query.c~       2007-02-03 13:22:21.000000000 +0900
> > +++ pool_process_query.c        2007-02-21 14:15:34.000000000 +0900
> > @@ -3261,7 +3261,7 @@
> >                 return POOL_CONTINUE;
> >         }
> > 
> > -       snprintf(qbuf, sizeof(qbuf), "LOCK TABLE %s IN SHARE ROW
> > EXCLUSIVE MODE", table);
> > +       snprintf(qbuf, sizeof(qbuf), "LOCK TABLE lock_%s IN SHARE ROW
> > EXCLUSIVE MODE", table);
> > 
> >         /* if we are not in a transaction block,
> >          * start a new transaction
> > 
> > これでVACUUM時にロックがかかるテーブルとinsert_lockがロックをかける
> > テーブルが違うので、VACUUM時のINSERTがロックされる問題が解決されると
> > 思いますが、このようなアプローチは間違っていますでしょうか?
> 
> おお、なるほど。確かに
> 
>   create table hoge (...);
>   create table lock_hoge (...);
> 
> と作っておいて、lock_hoge をロックすれば VACUUM でほとんど待たされるこ
> となくトランザクションは直列になります。
> 
> ただし、lock_hoge がないとエラーになってしまうので、このまま取りこむの
> は難しいです。かなりの思いつきなのですが pgpool 内でセマフォ管理するよ
> うにすればいけそうな気がしてきました。
> 
>   1. データベースとテーブル名をペアにしたキーを持つハッシュテーブルを
>      用意
>   2. INSERT 時にテーブル名を取得(現 pgpool でやっている)
>   3. データベース名とデーブル名からハッシュテーブルを検索
>   4. すでにセマフォがあれば semop() する
>   5. なければセマフォを作って semop() する
>   6. INSERT を実行
>   7. semop() でロック解除
> 
> うーん、ちょっと大変そうです…。

それに,複数のWebサーバそれぞれにpgpoolを配置するような構成ではうまく
いかないですよね...
--
Tatsuo Ishii
SRA OSS, Inc. Japan


pgpool-general-jp メーリングリストの案内