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