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

TANIDA Yutaka tanida @ sraoss.co.jp
2007年 2月 21日 (水) 15:29:36 JST


谷田です。

On Wed, 21 Feb 2007 15:26:40 +0900 (JST)
Tatsuo Ishii <ishii @ sraoss.co.jp> wrote:

> 石井です.
> 
> > 浅羽です。
> > 
> > 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を配置するような構成ではうまく
> いかないですよね...

少なくともその点に対しては、セマフォの代わりに、contrib/userlockとか、8.2の
advisary lock使えばよさそうですね。これも簡単ではないですが。

--
TANIDA Yutaka <tanida @ sraoss.co.jp>



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