[pgsql-jp: 35410] Re: pgpool経由のpg_dumpに失敗
Tatsuo Ishii
t-ishii @ sra.co.jp
2005年 5月 23日 (月) 21:57:44 JST
石井です.
> 木村と申します。
>
> pgpool-2.5経由のpg_dumpに失敗するという現象に遭遇しています。
> FreeBSD 4-STABLE上で、pgpoolでレプリケーションを行っているDBに対し、以
> 下のようにpg_dumpによるバックアップを試みました。DBはpg_dumpの出力(非
> 圧縮)で20MB程度と、かなり大きなものです。
>
> %pg_dump db_name |bzip2 -c > backup.bz2
>
> すると、途中でpg_dumpが以下のようなエラーを出力し、異常終了しました(ロ
> グ中、テーブル名等は伏せています)
>
> >pg_dump: connection not open
> >pg_dump: lost synchronization with server, resetting connection
> >pg_dump: SQL command to dump the contents of table "****" failed: PQendcopy() failed.
> >pg_dump: Error message from server: pg_dump: The command was: COPY ****** (*****************) TO stdout;
>
> pgpoolを-ndオプションで起動してログをとってみると、以下のようなエラー
> になっているようです(2行目)。
>
> >DEBUG: pid 72959: pool_read_string: read all from pending data. po:98 len:7
> >ERROR: pid 72959: pool_flush: fflush failed (Resource temporarily unavailable)
> >DEBUG: pid 72959: Query: ABORT
> >DEBUG: pid 72959: read kind from backend pending data C len: 6 po: 99
>
> どうもpool_steream.cの305行目の、fflushがEAGAINを返してそのままエラー
> になってる模様です。
>
>
> 次に、同じDBに対してパイプを使わずに以下のようにしてバックアップを取る
> と成功します。
>
> %pg_dump db_name > backup
> %bzip2 backup
>
> あまり良くわかってないのですが、パイプの受け先のbzip2の処理がいっぱい
> いっぱいになってパイプから読むのを一時停止 → pgpoolがflushしたので
> STDIOのバッファがあふれてエラーという事のような気がします。
>
> 今のところ実運用上は上記のようにdumpとbzip2での圧縮を2段構えに分ければ
> 問題ないのですが、もしかすると本質的な問題として「あまりに大きなデータ
> を送受信すると、EAGAINでエラーになるかも知れない」ということがないもの
> かと気になりましたので報告します。
>
> #パイプ経由にしてもたま〜に成功するし...やっぱりバッファの問題?
EAGAINが出ましたか.stdioライブラリの中でEAGAINのときは勝手にretryして
くれるのかと思っていたのですが...
とりあえず自前でretryするようにしてみました.以下のパッチを試していた
だけますか?
--
Tatsuo Ishii
RCS file: /cvsroot/pgpool/pgpool/pool_stream.c,v
retrieving revision 1.1.1.1
diff -c -r1.1.1.1 pool_stream.c
*** pool_stream.c 14 Feb 2005 14:52:21 -0000 1.1.1.1
--- pool_stream.c 23 May 2005 12:57:51 -0000
***************
*** 300,317 ****
*/
int pool_flush(POOL_CONNECTION *cp)
{
! if (fflush(cp->write_fd) != 0)
{
pool_error("pool_flush: fflush failed (%s)", strerror(errno));
if (cp->isbackend)
{
! notice_backend_error(!cp->issecondary_backend);
! exit(1);
}
else
{
! return -1;
}
}
return 0;
--- 300,325 ----
*/
int pool_flush(POOL_CONNECTION *cp)
{
! for (;;)
{
+ errno = 0;
+
+ if (fflush(cp->write_fd) == 0)
+ break;
+
+ if (errno == EAGAIN)
+ continue;
+
pool_error("pool_flush: fflush failed (%s)", strerror(errno));
if (cp->isbackend)
{
! notice_backend_error(!cp->issecondary_backend);
! exit(1);
}
else
{
! return -1;
}
}
return 0;
pgsql-jp メーリングリストの案内