[pgcluster: 79] Re: load balancer
Tatsuo Ishii
t-ishii @ sra.co.jp
2004年 2月 4日 (水) 23:00:26 JST
石井です.
> 川村と申します。
>
> FreeBSD 5.2R 上で PGCluster-1.0.6b を動かしていますが、ロードバランサを
> 経由して空文字列をフィールドとして持つテーブルにアクセスすると、signal 11
> が飛んで pglb が core dump してしまう現象が起きています。
>
> 直接マスタDBなりクラスタサーバなりに接続して同じテーブルにアクセスしても
> この問題は起きません。
>
> gdb で追ってみると、AsciiRow() 内の snprintf() で落ちているようです。
[snip]
> ソースを追ってみたところ、AsciiRow() での処理において、そのフィールドを
> 処理するかどうかの分岐条件を NULL かどうかだけで見ていて空文字列のフィー
> ルドを弾けず、その結果空文字列フィールドのデータを格納する領域を確保し
> ようとして malloc(0) が call されてしまい、その返り値であるポインタ変数
> buf に snprintf() でアクセスし、signal 11 が飛んでしまう、という現象が
> 起こっているように思います。
済みません.pgclusterにはpgpoolのコードの一部を利用していただいている
のですが,そもそもpgpoolにこのバグがありました.
> とりあえず size が 0 の場合は以降の処理を行わないというコードを追加して
> ひとおり動作はしているようですが、adhoc な感は否めません。この場合、ど
> のように修正するのがよいのでしょうか。
オリジナルのPostgreSQLでもsizeが0の場合はデータの送受信を行わないよう
に実装されていますので,この対処で正しいと思います.
参考までにpgpool 0.1.7に対する修正を付けておきます.川村さんの修正とほ
とんど同じです.
--
Tatsuo Ishii
*** pool_process_query.c 21 Jan 2004 08:19:53 -0000 1.5
--- pool_process_query.c 4 Feb 2004 12:23:17 -0000
***************
*** 422,441 ****
pool_write(frontend, &size, sizeof(int));
size = htonl(size) - 4;
! buf = malloc(size);
! if (buf == NULL)
{
! pool_error("AsciiRow: out of memory");
! return POOL_END;
}
- /* actual data */
- if (pool_read(backend, buf, size) < 0)
- return POOL_END;
-
- pool_write(frontend, buf, size);
- snprintf(msgbuf, Min(sizeof(msgbuf), size), "%s", buf);
pool_debug("AsciiRow: len:%d data: %s", size, msgbuf);
- free(buf);
}
mask >>= 1;
}
--- 422,452 ----
pool_write(frontend, &size, sizeof(int));
size = htonl(size) - 4;
!
! /* read and send actual data only when size > 0 */
! if (size > 0)
{
! buf = malloc(size);
! if (buf == NULL)
! {
! pool_error("AsciiRow: out of memory");
! return POOL_END;
! }
! /* actual data */
! if (pool_read(backend, buf, size) < 0)
! {
! free(buf);
! return POOL_END;
! }
! pool_write(frontend, buf, size);
! snprintf(msgbuf, Min(sizeof(msgbuf), size), "%s", buf);
! free(buf);
! }
! else
! {
! *msgbuf = '\0';
}
pool_debug("AsciiRow: len:%d data: %s", size, msgbuf);
}
mask >>= 1;
}
pgcluster メーリングリストの案内