]> granicus.if.org Git - pgbouncer/commitdiff
server_reset_query
authorMarko Kreen <markokr@gmail.com>
Wed, 1 Aug 2007 21:28:46 +0000 (21:28 +0000)
committerMarko Kreen <markokr@gmail.com>
Wed, 1 Aug 2007 21:28:46 +0000 (21:28 +0000)
NEWS
doc/todo.txt
etc/pgbouncer.ini
src/bouncer.h
src/main.c
src/objects.c

diff --git a/NEWS b/NEWS
index 0c5ebddc926fd29edc7cd0c5582d47d79d10ab6b..17f038d9f3e0949dd5b408897ff9c1d8e00228dd 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -7,6 +7,7 @@
     - Accept hostname in host=
     - Accept custom unix socket location in host=
     - Accept quoted values: password=' asd''foo'
+  * server_reset_query, to be sent immidiately after release
   * Cancel pkt sent for idle connection does not drop it anymore,
     just ReadyForQuery is re-sent.
   * Print FD limits on startup.
index 00ed3d3b0e61a7e791d0e222e82ed37486cfb452..da65c8622cef10ef2c185cd9f03530921ab66941 100644 (file)
@@ -3,7 +3,6 @@
 == Small stuff ==
 
  * cancel of SUSPEND/PAUSE
- * reset_command to be issued immidiately after release
  * suspend_timeout - drop stalled conns
 
 == Low-prio ==
index 13b4406fb6289dc89f62aa860e5ff0d0cdac4af1..a796f62f685cadd07a8879873d48dd4668cde45c 100644 (file)
@@ -58,17 +58,25 @@ stats_users = stats, root
 ;   statement    - after statement finishes
 pool_mode = session
 
-; When taking idle server into use, this query is ran first.
 ;
-; Query for session pooling:
-;   ABORT; RESET ALL; SET SESSION AUTHORIZATION DEFAULT
-; Query for statement/transaction pooling:
+; Query for cleaning connection immidiately after releasing from client.
+;
+; Query for 8.3+:
+;   DISCARD ALL;
+;
+; Older versions:
+;   RESET ALL; SET SESSION AUTHORIZATION DEFAULT
+;
+server_reset_query = 
+
+;
+; When taking idle server into use, this query is ran first.
 ;   SELECT 1
-; Empty query disables the functionality
+;
 server_check_query = select 1
 
 ; If server was used more recently that this many seconds ago,
-; skip the check query.  If 0, the check query is always ran.
+; skip the check query.  Value 0 may or may not run in immidiately.
 server_check_delay = 10
 
 ;;;
index cb930332f7a3cad65e43625cbd5294bafb5f0255..bf5e529de76cbb9d77d28bce17ef211c5a3258bf 100644 (file)
@@ -253,6 +253,7 @@ extern int cf_default_pool_size;
 
 extern usec_t cf_server_lifetime;
 extern usec_t cf_server_idle_timeout;
+extern char * cf_server_reset_query;
 extern char * cf_server_check_query;
 extern usec_t cf_server_check_delay;
 extern usec_t cf_server_connect_timeout;
index ea7f7107f71fce2f23eb97b40234a88ef8e90b02..e6b2af2883edf8c78c38256f7caa5d36e7d8e8d1 100644 (file)
@@ -77,6 +77,7 @@ char *cf_auth_file = "unconfigured_file";
 int cf_max_client_conn = 20;
 int cf_default_pool_size = 10;
 
+char *cf_server_reset_query = "";
 char *cf_server_check_query = "select 1";
 usec_t cf_server_check_delay = 30 * USEC;
 
@@ -117,6 +118,7 @@ ConfElem bouncer_params[] = {
 {"max_client_conn",    true, CF_INT, &cf_max_client_conn},
 {"default_pool_size",  true, CF_INT, &cf_default_pool_size},
 
+{"server_reset_query", true, CF_STR, &cf_server_reset_query},
 {"server_check_query", true, CF_STR, &cf_server_check_query},
 {"server_check_delay", true, CF_TIME, &cf_server_check_delay},
 {"query_timeout",      true, CF_TIME, &cf_query_timeout},
index b8304d1a0c8678fa00b5040ffe6461afbea3a797..ebb9b280e41846476d00dd124519cc862b11f4b0 100644 (file)
@@ -546,6 +546,37 @@ bool find_server(PgSocket *client)
        return res;
 }
 
+/* pick waiting client */
+static bool reuse_on_release(PgSocket *server)
+{
+       bool res = true;
+       PgPool *pool = server->pool;
+       PgSocket *client = first_socket(&pool->waiting_client_list);
+       if (client) {
+               activate_client(client);
+
+               /*
+                * As the activate_client() does full read loop,
+                * then it may happen that linked client close
+                * couses server close.  Report it.
+                */
+               if (server->state == SV_FREE || server->state == SV_JUSTFREE)
+                       res = false;
+       }
+       return res;
+}
+
+/* send reset query */
+static bool reset_on_release(PgSocket *server)
+{
+       bool res;
+       slog_debug(server, "Resetting: %s", cf_server_reset_query);
+       SEND_generic(res, server, 'Q', "s", cf_server_reset_query);
+       if (!res)
+               disconnect_server(server, false, "reset query failed");
+       return res;
+}
+
 /* connecting/active -> idle, unlink if needed */
 bool release_server(PgSocket *server)
 {
@@ -560,7 +591,15 @@ bool release_server(PgSocket *server)
                server->link->link = NULL;
                server->link = NULL;
 
-               if (cf_server_check_delay == 0 && *cf_server_check_query)
+               if (*cf_server_reset_query)
+                       /* notify reset is required */
+                       newstate = SV_TESTED;
+               else if (cf_server_check_delay == 0 && *cf_server_check_query)
+                       /*
+                        * depreceted: before reset_query, the check_delay = 0
+                        * was used to get same effect.  This if() can be removed
+                        * after couple of releases.
+                        */
                        newstate = SV_USED;
        case SV_USED:
        case SV_TESTED:
@@ -573,31 +612,15 @@ bool release_server(PgSocket *server)
        }
 
        Assert(server->link == NULL);
-
        log_debug("release_server: new state=%d", newstate);
-
        change_server_state(server, newstate);
 
-       /* immediately process waiters, to give fair chance */
-       if (newstate == SV_IDLE) {
-               PgSocket *client = first_socket(&pool->waiting_client_list);
-               if (client) {
-                       activate_client(client);
+       if (newstate == SV_IDLE)
+               /* immediately process waiters, to give fair chance */
+               return reuse_on_release(server);
+       else if (newstate == SV_TESTED)
+               return reset_on_release(server);
 
-                       /*
-                        * As the activate_client() does full read loop,
-                        * then it may happen that linked client close
-                        * couses server close.  Report it.
-                        */
-                       switch (server->state) {
-                       case SV_FREE:
-                       case SV_JUSTFREE:
-                               return false;
-                       default:
-                               break;
-                       }
-               }
-       }
        return true;
 }