[pgsql-jp: 37335] Re: popoolとシーケンスキー

koyama mlus @ hintmark.com
2006年 7月 5日 (水) 01:18:25 JST


xeon-koyama です

石井さん、島田@Storgateさん 詳細なご返答感謝です。

>> 一見、db1, db2 に同じ順番で  INSERT文を送信すれば、 
>> その条件を
>> 満たしそうですが、各 backend process の内での実際の処理進 
>> 行が
>> 各バックエンドプロセスにおける SQLの受信順序になることは、
>> postgresバックエンドが複数の個別プロセスであるために保証され
>> ないかと。。
>> (独立なプロセスは kernel によって勝手にスケジュールされま 
>> す)

なるほど。

>> 従って、pgpool の説明にもあるように、明示的にテーブルを LOCK
>> する様な、何らかの仕込みが必要になるのでは。

そうですか....

> 
> 各セッション内ではmasterでのnextvalの実行後にsecondaryでnextvalが実行
> されるということが保たれています.しかし,全体で見ると,masterでは
> session0->session1の順でnextvalが実行されるのに対し,secondaryでは
> session1->session0の順でnextvalが実行されてしまってます.これがまずい
> わけですね.

そうなります。

> masterでもsecondaryでも必ずsession0->session1の順でnextvalを実行させる
> ための一つの方法がテーブルロックです.テーブルロックを併用すると以下の
> 様になります(nextvalの後のcommitは省略してあります).
> 
> 	    master		       secondary
>    session 0	session 1	session 0   session 1
>    ------------------------------------------------------
>    lock
>                                 lock
>    nextval	
>                                 nextval
>                 lock
>                                              lock
>                 nextval
>                                              nextval
>    ------------------------------------------------------
> 
> この状態であれば,シーケンスが狂うことはありません.この例ではセッショ
> ンが2つですが,セッションが3つ以上でも同じことが言えます.
> もちろんテーブルロックを使うことによってトランザクションの同時実行性が
> 損なわれてしまうのは好ましいことではありませんが,現状ではシーケンス値
> を保証しようとするとテーブルロックを使うなどしてSQLの実行順序を保証し
> なければなりません.

LOCK コマンドを使えば、多少のトランザクションの平行性が犠牲に
なるが、シーケンス値は同じでセットされるという事ですね。

今回のケースでの、シーケンス利用テーブルへの挿入は、

BEGIN WORK;
LOCK TABLE テーブル名
COMMIT WORK;

を発行してやれば、良いという事がわかりました。

詳細に渡る解説、ありがとうございました。

TO 石井さん
 改訂5 シーラカンス本 P517の insert_lock
  の説だけでは、私にはわかりにくかったのですが、
  今回のご返答で、とてもよくわかりました。


 










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