[pgsql-jp: 33637] Re: pgpool 2.0.2 報告

Jun Kitamura kitamura @ zoozee.jp
2004年 7月 13日 (火) 11:23:19 JST


北村です。

> > 以前、西尾さんが発見された「order by 問題([pgsql-jp: 33436])」
> > の時は、1行全体のバイナリでチェックしていたって事ですかね(ソー
> > ス見れば良いんで返答無用)。その後、ヘッダの長さのチェックだ
> > けに変えた・・・と。ある意味、以前の方法ならば、primary と 
> > secondary 間の厳密なチェックが可能なわけですね。捨てがたいか
> > もw。
> 
> いや,以前の方法もそんなに厳密なわけではないです:-)
> 
> V2.0:
> 	行データのパケット長がマスタとセカンダリで違っていたらアウト
> 
> V2.0.1以降:
> 	行データのパケット長がマスタとセカンダリで違っていてもOK.単に
> 	セカンダリのデータを読み捨てる

パケット長のチェックだけでしたか。バイナリチェックなんてして
いたらレスポンスが悪すぎますかね。

ここで「新たな疑問」が出るのですが、1行の長さチェックだけな
らば、西尾さんの報告された([pgsql-jp: 33436])ケースがエラー
となる理由がわかりません。ORDER を付けるか付けないかにより、
タプルの順序が異なるだけで、カラムの数、タプルの数、(あの場
合 int と 1文字text だけなので)1行の長さ、全て一致しているハ
ズですよ・・ね??

V2.0.1, V2.0, バイナリチェック と、厳密さを選択できると良い
かもしれませんね。

> > 3)が妥当な気がします。
> > 当初、2)が良い(あるいは実装されている)かとも思いましたが、こ
> > と random() で言えば、ユーザー定義関数内の random() などは 
> > pgpool では拾えないのでどうしようもないです。となると、ユー
> > ザー定義関数側で独自の擬似乱数関数を使うなどの方法になり、結
> > 局 3) ですね。
> > シーケンス(シリアル型)も、最大値+1 というユーザー定義関数を
> > 作れば解決です(当然この場合、シーケンスの「番号先確保で高速
> > 処理」の恩恵は受けられないですが)。
> 
> そうでしょうか?pgpoolではマスタの次にセカンダリが問い合わせを実行する
> ことは(STRICTモードならば)保証されますが,複数のセッションが同時に走っ
> た場合,セッション1のマスタの次にセッション2のマスタの問い合わせが実行
> されたが,セッション1のセカンダリの問い合わせの前にセッション2のセカン
> ダリの問い合わせが実行される,ということが起こり得ます.そうなると最大
> 値+1のユーザ定義関数を実行してもマスタとセカンダリで結果が異なってしま
> うことになります.

!!!たしかに。
まずい・・・と思ったのですが、テーブルロックをすれば、セッショ
ン2 は セッション1 を待つので問題ないですね(?デッドロックし
ちゃう??)。
そもそも、最大値+1 をユーザー定義関数でテーブルロックせずに
しようというのが間違っていた、って事ですね(前、本MLで自分が
そう言ってたような(恥))。

(begin - commit で挟んで STRICTモードを強制しても)
S1:Session1  S2:Session2  P:Primary  S:Secondary
↓こうなることを期待しているが、
S1  P begin   max++   insert   commit       val:1
    S  begin   max++   insert   commit      val:1
S2  P   begin   max++   insert   commit     val:2
    S    begin   max++   insert   commit    val:2

↓こうなる可能性がある
S1  P begin   max++   insert   commit       val:1
    S    begin   max++   insert   commit    val:2
S2  P  begin   max++   insert   commit      val:2
    S   begin   max++   insert   commit     val:1

↓ロックすればOK(たぶん)
S1  P b   lock   mx++   i   c
    S    b   lock   mx++   i   c
S2  P  b   (wait)........... lock   mx++ i   c
    S   b  (wait).............. lock   mx++ i   c
b:begin   mx++:max++   i:insert   c:commit 
(wait)Lock解除待ち

> 置き換え用の関数を作るとしたら,マスタとセカンダリで同じ値を必ず返す保
> 証をする仕掛けを別に考える必要があると思います.たぶん,マスタの関数と
> セカンダリの関数が,直接あるいは間接に通信しあうようなことが必要になる
> でしょう.

ですね。大掛かりになってきますね。
解決方法がどれになるにせよ、pgpool を使うにあたり「できなく
なること」をまとめ、それを避ける方がよさそうですね。
結局、石井さんがおっしゃってた「頭の痛いところ」に戻ってしま
いました。じっくり考えましょうw。




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