[pgsql-jp: 33438] Re: pgpoolでsecondary
Tatsuo Ishii
t-ishii @ sra.co.jp
2004年 6月 30日 (水) 21:36:34 JST
石井です.
> 西尾です。
>
> > げ,確かにそうなってしまうようです.とりあえずパッチを作りましたので,
> > 試してみていただけませんか?
> パッチあててみました。
> backend_host_name = ''
> secondary_backend_host_name = 'XXX.XXX.XXX.XXX'
> で、マスタは、UNIXドメインソケット、セカンダリはTCPソケットで問題なく
> 接続されているようです。
> 対応、ありがとうございました。
どういたしまして.
> それと、上記とは別件ですが、pgpool越しにデータを削除、更新を繰り返してると
> 以下のような状態が発生します。
>
> ・マスタ
> table Alpha
> i |j
> ---+--
> 1 |A
> 2 |B
> 3 |C
>
> table Alpha
> i |j
> ---+--
> 1 |A
> 3 |C
> 2 |B
>
> 上記はSELECTしたときの表示順をイメージしています。
> (データそのものに相違はないが、ディスク上での記録順が異なるよう)
もし,複数のセッションを同時に走らせ,それぞれ削除,更新をしていたとす
ると,これは起こり得ます.というのも,pgpoolでは同じセッションの中では
(strict modeならば)必ずmasterのクエリが実行されてからsecondaryのクエリ
が実行されることが保証されているものの,異なるセッションの間ではそうい
う保証はないからです.
たとえばS1がセッション1,S2がセッション2だとすると,以下のようなことが
起こり得ます.
S1.master: update table set i = 3...
S2.master: update table set i = 2...
S2.secondary: update table set i = 2...
S1.secondary: update table set i = 3...
この結果,最初
i |j
---+--
1 |A
2 |B
3 |C
だったのが
masterでは
i |j
---+--
1 |A
3 |C
2 |B
secondaryでは
i |j
---+--
1 |A
2 |B
3 |C
となります.
> この状態で、"SELECT * FROM Alpha"を行うと、
>
> out of memory
> server closed the connection unexpectedly
> This probably means the server terminated abnormally
> before or while processing the request.
> The connection to the server was lost. Attempting reset: Succeeded.
>
> となり、処理がストップします。
> で、このときのログを眺めていると、pgpoolでは、SELECTの抽出結果を1カラム毎に
> チェックしいて、2カラム目で内容が異なるためABORTしているようでした。
> そこで、"SELECT * FROM Alpha ORDER BY i"とするとエラーは発生しませんでした。
>
> 上記の様に、ディスク上のデータの並びがどうゆう理由で異なるのかは不明ですが、
> copyコマンドで出力したものに差異はありませんでした。
>
> ちなみに環境は、マスタ、セカンダリ共に
> Solaris8、Postgres 7.5.3です。
確認ですが,7.5.3ではなくて,7.4.3ですよね?まだ7.5はリリースされてま
せんから...
7.4.xでは上のような状況になってします(ちなみに7.3.xでは起きません).
> pgpoolのバグという訳ではないようですが、一応ご報告までに。
これだとあまりに不便なので,データ内容のちょっとチェックを甘くしました
(厳密なチェックは不可能なのでやむを得ないと思います).
以下のパッチをお試し下さい.
--
Tatsuo Ishii
*** pool_process_query.c 18 Jun 2004 12:11:06 -0000 1.22
--- pool_process_query.c 30 Jun 2004 11:23:56 -0000
***************
*** 1726,1746 ****
*/
POOL_STATUS SimpleForwardToFrontend(char kind, POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend)
{
! int len;
! int sendlen;
char *p;
pool_write(frontend, &kind, 1);
! len = pool_read_message_length(backend);
! if (len < 0)
{
return POOL_END;
}
! sendlen = htonl(len);
! pool_write(frontend, &sendlen, sizeof(sendlen));
len -= 4;
p = pool_read2(MASTER(backend), len);
--- 1726,1763 ----
*/
POOL_STATUS SimpleForwardToFrontend(char kind, POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend)
{
! int len, len1;
char *p;
+ int status;
pool_write(frontend, &kind, 1);
! status = pool_read(MASTER(backend), &len, sizeof(len));
! if (status < 0)
{
+ pool_error("SimpleForwardToFrontend: error while reading message length");
return POOL_END;
}
! if (REPLICATION)
! {
! status = pool_read(SECONDARY(backend), &len1, sizeof(len1));
! if (status < 0)
! {
! pool_error("SimpleForwardToFrontend: error while reading message length from secondary backend");
! return POOL_END;
! }
!
! if (len != len1)
! {
! pool_log("SimpleForwardToFrontend: length does not match between backends master(%d) secondary(%d)",
! ntohl(len), ntohl(len1));
! }
! }
!
! pool_write(frontend, &len, sizeof(len));
+ len = ntohl(len);
len -= 4;
p = pool_read2(MASTER(backend), len);
***************
*** 1748,1755 ****
return POOL_END;
if (REPLICATION)
! if (pool_read2(SECONDARY(backend), len) == NULL)
return POOL_END;
return pool_write(frontend, p, len);
}
--- 1765,1776 ----
return POOL_END;
if (REPLICATION)
! {
! len1 = ntohl(len1);
! len1 -= 4;
! if (pool_read2(SECONDARY(backend), len1) == NULL)
return POOL_END;
+ }
return pool_write(frontend, p, len);
}
pgsql-jp メーリングリストの案内