From 025cbb7f8b93fe4996c5847e37a6e02f0443bfae Mon Sep 17 00:00:00 2001 From: Tatsuo Ishii Date: Mon, 18 Jul 2005 01:42:49 +0000 Subject: [PATCH] version 2.6.1. See README for more detailed changes. --- ChangeLog | 10 +++ NEWS | 17 +++++ README | 2 +- README.euc_jp | 2 +- child.c | 8 +- configure | 2 +- configure.in | 2 +- pool.h | 6 +- pool_process_query.c | 4 +- pool_stream.c | 174 ++++++++++++++++++++++++++++++++++++++----- 10 files changed, 196 insertions(+), 31 deletions(-) diff --git a/ChangeLog b/ChangeLog index 4905d35..9939390 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,13 @@ +2005-07-18 + * version 2.6.1 + * set non blocking to sockets for frontend. + * remove stdio usage from pool_write/pool_flush. Stdio libs have + fundanmental problems with non blocking sockets + * do not raise failover when read() read encounters EOF. It seems it + is a oversight. Backend crush may cause that but it does not + immediately mean postmaster crush + * retries with EINTR or EAGAIN in pool_stream modules + 2005-06-25 * version 2.6 * fix memory leak in pool_error() diff --git a/NEWS b/NEWS index 63590bb..d0d9af4 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,20 @@ +2.6.1(kala) 2005/7/18 + + o ¥Õ¥í¥ó¥È¥¨¥ó¥É¤È¤Î¥½¥±¥Ã¥È¤ònon blocking¤Ë¤·¤¿(Linux¤Ç¤Ï¡¤°ÊÁ° + ¤«¤énon blocking¤À¤Ã¤¿)¡¥°ì±þÆâÉô½èÍý¤Ïnon blocking¤Ç¤âÂç¾æÉ× + ¤Ë¤Ê¤è¤¦¤Ë¤Ê¤Ã¤Æ¤¤¤ë¤Ï¤º¤À¤¬¡¤Â¬Äê¤Î·ë²Ìnon blocking¤À¤«¤é¤È¸À¤Ã + ¤ÆÀ­Ç½¤¬¾å¤¬¤ë¤è¤¦¤Ê¤³¤È¤Ï¤Ê¤«¤Ã¤¿¡¥[pgsql-jp: 35721]»²¾È¡¥ + + o stdio¥é¥¤¥Ö¥é¥ê¤Ïnon blocking¥½¥±¥Ã¥È¤ÇÀµ¤·¤¯Æ°¤«¤Ê¤¤¤È¤Î»ØÅ¦ + ¤ò¼õ¤±¡¤fwrite/fflush¤Î»ÈÍѤò»ß¤á¤Æ¼«Á°¤Î¥Ð¥Ã¥Õ¥¡¥ê¥ó¥°¥ë¡¼¥Á + ¥ó¤ËÃÖ¤­´¹¤¨¤¿¡¥ + + o ¥Ð¥Ã¥¯¥¨¥ó¥É¤«¤é¤Îread()¤ÇEOF¤ò¸¡ÃΤ·¤¿¤È¤­¤Ë½ÌÂà/¥Õ¥§¥¤¥ë¥ª¡¼ + ¥Ð¤¹¤ë¤Î¤ò»ß¤á¤¿(²á¾êÈ¿±þ)¡¥ + + o pool_stream¥â¥¸¥å¡¼¥ë¤Ç¡¤EINTR/EGAIN¤Î¤È¤­¤Ë¥ê¥È¥é¥¤¤¹¤ë¤è¤¦¤Ë + ¤·¤¿¡¥ + 2.6(kala) 2005/06/25 o pool_error etc.¤Ç¡¤asprintf¤Î¸å¤Çfree¤·¤Æ¤¤¤Ê¤«¤Ã¤¿¤Î¤ò½¤Àµ¡¥ diff --git a/README b/README index 4f6f68e..5424999 100644 --- a/README +++ b/README @@ -1,6 +1,6 @@ $Header$ -pgpool version 2.6(kala) README +pgpool version 2.6.1(kala) README 1. What is pgpool diff --git a/README.euc_jp b/README.euc_jp index 48b83aa..4505c53 100644 --- a/README.euc_jp +++ b/README.euc_jp @@ -1,6 +1,6 @@ $Header$ -pgpool version 2.6(kala) README +pgpool version 2.6.1(kala) README 1. pgpool¤È¤Ï diff --git a/child.c b/child.c index 7a9d890..165aa59 100644 --- a/child.c +++ b/child.c @@ -48,8 +48,6 @@ #ifdef NONE_BLOCK static void set_nonblock(int fd); -#endif -#ifdef NOT_USED static void unset_nonblock(int fd); #endif @@ -149,9 +147,11 @@ void do_child(int unix_fd, int inet_fd) continue; } -#ifdef NOT_USED /* set frontend fd to blocking */ unset_nonblock(frontend->fd); + +#ifdef NOT_USED + set_nonblock(frontend->fd); #endif /* set busy flag and clear child idle timer */ @@ -384,7 +384,6 @@ static void set_nonblock(int fd) } #endif -#ifdef NOT_USED /* * unset non-block flag */ @@ -405,7 +404,6 @@ static void unset_nonblock(int fd) exit(1); } } -#endif /* * perform accept() and return new fd diff --git a/configure b/configure index 72e7eb8..4b69cfa 100755 --- a/configure +++ b/configure @@ -2603,7 +2603,7 @@ fi # Define the identity of the package. PACKAGE=pgpool - VERSION=2.6 + VERSION=2.6.1 cat >>confdefs.h <<_ACEOF diff --git a/configure.in b/configure.in index bc64790..120065d 100644 --- a/configure.in +++ b/configure.in @@ -4,7 +4,7 @@ AC_INIT dnl Checks for programs. AC_PROG_CC -AM_INIT_AUTOMAKE(pgpool, 2.6) +AM_INIT_AUTOMAKE(pgpool, 2.6.1) AM_PROG_LEX diff --git a/pool.h b/pool.h index dbb46ef..56af7a7 100644 --- a/pool.h +++ b/pool.h @@ -171,7 +171,10 @@ typedef struct { */ typedef struct { int fd; /* fd for connection */ - FILE *write_fd; /* stream write connection */ + + char *wbuf; /* write buffer for the connection */ + int wbufsz; /* write buffer size */ + int wbufpo; /* buffer offset */ char *hp; /* pending data buffer head address */ int po; /* pending data offset */ @@ -269,6 +272,7 @@ extern int pool_read(POOL_CONNECTION *cp, void *buf, int len); extern char *pool_read2(POOL_CONNECTION *cp, int len); extern int pool_write(POOL_CONNECTION *cp, void *buf, int len); extern int pool_flush(POOL_CONNECTION *cp); +extern int pool_flush_it(POOL_CONNECTION *cp); extern int pool_write_and_flush(POOL_CONNECTION *cp, void *buf, int len); extern char *pool_read_string(POOL_CONNECTION *cp, int *len, int line); diff --git a/pool_process_query.c b/pool_process_query.c index a9b2078..42fc11a 100644 --- a/pool_process_query.c +++ b/pool_process_query.c @@ -2002,7 +2002,7 @@ void pool_send_frontend_exits(POOL_CONNECTION_POOL *backend) * famouse "lostsynchronization with server, resettin g * connection" message) */ - fflush(MASTER(backend)->write_fd); + pool_flush_it(MASTER(backend)); if (DUAL_MODE) { @@ -2012,7 +2012,7 @@ void pool_send_frontend_exits(POOL_CONNECTION_POOL *backend) len = htonl(4); pool_write(SECONDARY(backend), &len, sizeof(len)); } - fflush(SECONDARY(backend)->write_fd); + pool_flush_it(SECONDARY(backend)); } } diff --git a/pool_stream.c b/pool_stream.c index 9d63ede..58f4527 100644 --- a/pool_stream.c +++ b/pool_stream.c @@ -33,6 +33,7 @@ #include "pool.h" #define READBUFSZ 1024 +#define WRITEBUFSZ 8192 static int mystrlen(char *str, int upper, int *flag); static int mystrlinelen(char *str, int upper, int *flag); @@ -56,13 +57,15 @@ POOL_CONNECTION *pool_open(int fd) memset(cp, 0, sizeof(*cp)); - cp->write_fd = fdopen(fd, "w"); - if (cp->write_fd == NULL) + /* initialize write buffer */ + cp->wbuf = malloc(WRITEBUFSZ); + if (cp->wbuf == NULL) { - pool_error("pool_open: fdopen failed: %s",strerror(errno)); - free(cp); + pool_error("pool_open: malloc failed"); return NULL; } + cp->wbufsz = WRITEBUFSZ; + cp->wbufpo = 0; /* initialize pending data buffer */ cp->hp = malloc(READBUFSZ); @@ -88,7 +91,7 @@ POOL_CONNECTION *pool_open(int fd) */ void pool_close(POOL_CONNECTION *cp) { - fclose(cp->write_fd); + free(cp->wbuf); free(cp->hp); if (cp->sbuf) free(cp->sbuf); @@ -136,6 +139,12 @@ int pool_read(POOL_CONNECTION *cp, void *buf, int len) readlen = read(cp->fd, readbuf, READBUFSZ); if (readlen == -1) { + if (errno == EINTR || errno == EAGAIN) + { + pool_debug("pool_read: retrying due to %s", strerror(errno)); + continue; + } + pool_error("pool_read: read failed (%s)", strerror(errno)); if (cp->isbackend) @@ -151,13 +160,16 @@ int pool_read(POOL_CONNECTION *cp, void *buf, int len) } else if (readlen == 0) { - pool_error("pool_read: EOF encountered"); - if (cp->isbackend) { + pool_error("pool_read2: EOF encountered with backend"); + return -1; + +#ifdef NOT_USED /* fatal error, notice to parent and exit */ notice_backend_error(!cp->issecondary_backend); exit(1); +#endif } else { @@ -244,6 +256,12 @@ char *pool_read2(POOL_CONNECTION *cp, int len) readlen = read(cp->fd, buf, len); if (readlen == -1) { + if (errno == EINTR || errno == EAGAIN) + { + pool_debug("pool_read2: retrying due to %s", strerror(errno)); + continue; + } + pool_error("pool_read2: read failed (%s)", strerror(errno)); if (cp->isbackend) @@ -259,13 +277,16 @@ char *pool_read2(POOL_CONNECTION *cp, int len) } else if (readlen == 0) { - pool_error("pool_read2: EOF encountered"); - if (cp->isbackend) { + pool_error("pool_read2: EOF encountered with backend"); + return NULL; + +#ifdef NOT_USED /* fatal error, notice to parent and exit */ notice_backend_error(!cp->issecondary_backend); exit(1); +#endif } else { @@ -284,34 +305,149 @@ char *pool_read2(POOL_CONNECTION *cp, int len) } /* -* write len bytes from cp +* write len bytes to cp the write buffer. * returns 0 on success otherwise -1. */ int pool_write(POOL_CONNECTION *cp, void *buf, int len) { - if (!cp->no_forward) - fwrite(buf, len, 1, cp->write_fd); + int reqlen; + + if (len < 0) + { + pool_error("pool_write: invalid request size: %d", len); + return -1; + } + + if (cp->no_forward) + return 0; + + /* check buffer size */ + reqlen = cp->wbufpo + len; + + if (reqlen > cp->wbufsz) + { + char *p; + + reqlen = (reqlen/WRITEBUFSZ+1)*WRITEBUFSZ; + p = realloc(cp->wbuf, reqlen); + if (p == NULL) + { + pool_error("pool_write: realloc failed"); + return -1; + } + cp->wbuf = p; + cp->wbufsz = reqlen; + } + + memcpy(cp->wbuf+cp->wbufpo, buf, len); + cp->wbufpo += len; return 0; } /* -* flush write buffer -*/ -int pool_flush(POOL_CONNECTION *cp) + * flush write buffer + */ +int pool_flush_it(POOL_CONNECTION *cp) { + int sts; + int wlen; + int offset; + wlen = cp->wbufpo; + + if (wlen == 0) + { + return 0; + } + + offset = 0; + for (;;) { errno = 0; - if (fflush(cp->write_fd) == 0) - break; +#ifdef NOT_USED + if (!cp->isbackend) + { + fd_set writemask; + fd_set exceptmask; + + FD_ZERO(&writemask); + FD_ZERO(&exceptmask); + FD_SET(cp->fd, &writemask); + FD_SET(cp->fd, &exceptmask); + + sts = select(cp->fd+1, NULL, &writemask, &exceptmask, NULL); + if (sts == -1) + { + if (errno == EAGAIN || errno == EINTR || errno == EWOULDBLOCK) + continue; + + pool_error("pool_flush_it: select() failed. reason: %s", strerror(errno)); + return -1; + } + else if (sts == 0) + { + continue; + } + else if (FD_ISSET(cp->fd, &exceptmask)) + { + pool_log("pool_flush_it: exception occured"); + return -1; + } + } +#endif + sts = write(cp->fd, cp->wbuf + offset, wlen); + + if (sts > 0) + { + wlen -= sts; + + if (wlen == 0) + { + /* write completed */ + break; + } + + else if (wlen < 0) + { + pool_error("pool_flush_it: invalid write size %d", sts); + return -1; + } + + else + { + /* need to write remaining data */ + offset += sts; + continue; + } + } - if (errno == EAGAIN) + else if (errno == EAGAIN || errno == EINTR) + { continue; + } + + else + { + pool_error("pool_flush_it: write failed (%s) offset: %d wlen: %d", + strerror(errno), offset, wlen); + return -1; + } + } - pool_error("pool_flush: fflush failed (%s)", strerror(errno)); + cp->wbufpo = 0; + + return 0; +} +/* +* flush write buffer and degenerate/failover if error occurs +*/ +int pool_flush(POOL_CONNECTION *cp) +{ + if (pool_flush_it(cp) == -1) + { if (cp->isbackend) { notice_backend_error(!cp->issecondary_backend); -- 2.39.5