[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 メーリングリストの案内