From: Marko Kreen Date: Wed, 11 Apr 2007 09:24:48 +0000 (+0000) Subject: Version 1.0.4 X-Git-Tag: pgbouncer_1_0_4 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=507b7725f85b5b8356cf4883cc584a7d4a2bbb32;p=pgbouncer Version 1.0.4 * Notice from idle server tagged server dirty. release_server() did not expect it. Fix it by dropping them. --- diff --git a/NEWS b/NEWS index d908aca..af20ea5 100644 --- a/NEWS +++ b/NEWS @@ -1,4 +1,10 @@ +2007-04-11 - PgBouncer 1.0.4 - "Last 'last' bug" + + * Notice from idle server tagged server dirty. + release_server() did not expect it. Fix it + by dropping them. + 2007-04-11 - PgBouncer 1.0.3 - "Fearless Fork" = Fixes = diff --git a/configure.ac b/configure.ac index a4a4146..aab76a7 100644 --- a/configure.ac +++ b/configure.ac @@ -1,6 +1,6 @@ dnl Process this file with autoconf to produce a configure script. -AC_INIT(pgbouncer, 1.0.3) +AC_INIT(pgbouncer, 1.0.4) AC_CONFIG_SRCDIR(src/bouncer.h) AC_CONFIG_HEADER(config.h) diff --git a/debian/changelog b/debian/changelog index b7e94a1..e26397a 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,9 @@ +pgbouncer (1.0.4-1) unstable; urgency=low + + * last bug, honestly. + + -- Marko Kreen Wed, 11 Apr 2007 12:03:52 +0300 + pgbouncer (1.0.3-1) unstable; urgency=low * more error handling fixes. diff --git a/src/janitor.c b/src/janitor.c index a7c392c..8caf30b 100644 --- a/src/janitor.c +++ b/src/janitor.c @@ -113,7 +113,15 @@ static void launch_recheck(PgPool *pool) PgSocket *server; bool res = true; - server = first_socket(&pool->used_server_list); + /* find clean server */ + while (1) { + server = first_socket(&pool->used_server_list); + if (!server) + return; + if (server->ready) + break; + disconnect_server(server, true, "idle server got dirty"); + } /* is the check needed? */ if (q == NULL || q[0] == 0) @@ -308,6 +316,10 @@ static void check_unused_servers(StatList *slist, usec_t now, bool idle_test) if (server->close_needed) disconnect_server(server, true, "db conf changed"); + else if (server->state == SV_IDLE && !server->ready) + disconnect_server(server, true, "SV_IDLE server got dirty"); + else if (server->state == SV_USED && !server->ready) + disconnect_server(server, true, "SV_USED server got dirty"); else if (cf_server_idle_timeout > 0 && idle > cf_server_idle_timeout) disconnect_server(server, true, "server idle timeout"); else if (cf_server_lifetime > 0 && age > cf_server_lifetime) diff --git a/src/objects.c b/src/objects.c index ea4cf88..666e00c 100644 --- a/src/objects.c +++ b/src/objects.c @@ -523,8 +523,14 @@ bool find_server(PgSocket *client) /* try to get idle server, if allowed */ if (cf_pause_mode == P_PAUSE) server = NULL; - else - server = first_socket(&pool->idle_server_list); + else { + while (1) { + server = first_socket(&pool->idle_server_list); + if (!server || server->ready) + break; + disconnect_server(server, true, "idle server got dirty"); + } + } /* link or send to waiters list */ if (server) { diff --git a/src/server.c b/src/server.c index 8bae665..b9093f9 100644 --- a/src/server.c +++ b/src/server.c @@ -70,7 +70,6 @@ static bool handle_server_startup(PgSocket *server, MBuf *pkt) /* got all params */ finish_welcome_msg(server); - // FIXME: res check res = release_server(server); /* let the takeover process handle it */ @@ -138,6 +137,16 @@ static bool handle_server_work(PgSocket *server, MBuf *pkt) return false; } + /* + * 'E' and 'N' packets currently set ->ready to 0. Correct would + * be to leave ->ready as-is, because overal TX state stays same. + * It matters for connections in IDLE or USED state which get dirty + * suddenly but should not as they are still usable. + * + * But the 'E' or 'N' packet between transactions signifies probably + * dying backend. This its better to tag server as dirty and drop + * it later. + */ case 'E': /* ErrorResponse */ case 'N': /* NoticeResponse */