]> granicus.if.org Git - pgbouncer/commitdiff
RECONNECT command
authorPeter Eisentraut <peter@eisentraut.org>
Wed, 25 Jul 2018 09:18:01 +0000 (11:18 +0200)
committerPetr Jelinek <pjmodos@pjmodos.net>
Fri, 3 Aug 2018 14:02:59 +0000 (16:02 +0200)
doc/usage.rst
src/admin.c
test/test.sh

index aeac92dcc1ae5b2f2088961cf62d14b84ab62da0..3e62d8ccdcde5ed88e29f58e84ae22c31219c616 100644 (file)
@@ -276,7 +276,7 @@ wait_us
 close_needed
     1 if the connection will be closed as soon as possible,
     because a configuration file reload or DNS update changed the
-    connection information.
+    connection information or **RECONNECT** was issued.
 
 ptr
     Address of internal object for this connection.
@@ -596,6 +596,33 @@ ENABLE db;
 
 Allow new client connections after a previous **DISABLE** command.
 
+RECONNECT [db];
+---------------
+
+Close each open server connection for the given database, or all
+databases, after it is released (according to the pooling mode), even
+if its lifetime is not up yet.  New server connections can be made
+immediately and will connect as necessary according to the pool size
+settings.
+
+This command is useful when the server connection setup has changed,
+for example to perform a gradual switchover to a new server.  It is
+*not* necessary to run this command when the connection string in
+pgbouncer.ini has been changed and reloaded (see **RELOAD**) or when
+DNS resolution has changed, because then the equivalent of this
+command will be run automatically.  This command is only necessary if
+something downstream of PgBouncer routes the connections.
+
+After this command is run, there could be an extended period where
+some server connections go to an old destination and some server
+connections go to a new destination.  This is likely only sensible
+when switching read-only traffic between read-only replicas, or when
+switching between nodes of a multimaster replication setup.  If all
+connections need to be switched at the same time, **PAUSE** is
+recommended instead.  To close server connections without waiting (for
+example, in emergency failover rather than gradual switchover
+scenarios), also consider **KILL**.
+
 KILL db;
 --------
 
index e4dd684e9a609c6f6c165b5a7b5995ea8a6c5242..a86fb45a7a3da29a4a4a1af800b4c8ca3bb56861 100644 (file)
@@ -1075,6 +1075,38 @@ static bool admin_cmd_pause(PgSocket *admin, const char *arg)
        return true;
 }
 
+/* Command: RECONNECT */
+static bool admin_cmd_reconnect(PgSocket *admin, const char *arg)
+{
+       if (!admin->admin_user)
+               return admin_error(admin, "admin access needed");
+
+       if (!arg[0]) {
+               struct List *item;
+               PgPool *pool;
+
+               log_info("RECONNECT command issued");
+               statlist_for_each(item, &pool_list) {
+                       pool = container_of(item, PgPool, head);
+                       if (pool->db->admin)
+                               continue;
+                       tag_database_dirty(pool->db);
+               }
+       } else {
+               PgDatabase *db;
+
+               log_info("RECONNECT '%s' command issued", arg);
+               db = find_or_register_database(admin, arg);
+               if (db == NULL)
+                       return admin_error(admin, "no such database: %s", arg);
+               if (db == admin->pool->db)
+                       return admin_error(admin, "cannot reconnect admin db: %s", arg);
+               tag_database_dirty(db);
+       }
+
+       return admin_ready(admin, "RECONNECT");
+}
+
 /* Command: DISABLE */
 static bool admin_cmd_disable(PgSocket *admin, const char *arg)
 {
@@ -1210,6 +1242,7 @@ static bool admin_show_help(PgSocket *admin, const char *arg)
                "\tRESUME [<db>]\n"
                "\tDISABLE <db>\n"
                "\tENABLE <db>\n"
+               "\tRECONNECT [<db>]\n"
                "\tKILL <db>\n"
                "\tSUSPEND\n"
                "\tSHUTDOWN", "");
@@ -1285,6 +1318,7 @@ static struct cmd_lookup cmd_list [] = {
        {"enable", admin_cmd_enable},
        {"kill", admin_cmd_kill},
        {"pause", admin_cmd_pause},
+       {"reconnect", admin_cmd_reconnect},
        {"reload", admin_cmd_reload},
        {"resume", admin_cmd_resume},
        {"select", admin_cmd_show},
index 2ebb5303fabd1425746ea4c28abc1581d46af31b..5fc6758ef4ebf5031163cb786b965bfca125e380 100755 (executable)
@@ -458,6 +458,16 @@ test_database_change() {
        test "$db1" = "p1" -a "$db2" = "p0"
 }
 
+# test reconnect
+test_reconnect() {
+       bp1=`psql -X -tAq -c "select pg_backend_pid()" p1`
+       admin "reconnect p1"
+       sleep 1
+       bp2=`psql -X -tAq -c "select pg_backend_pid()" p1`
+       echo "bp1=$bp1 bp2=$bp2"
+       test "$bp1" != "$bp2"
+}
+
 # test auth_user
 test_auth_user() {
        admin "set auth_type='md5'"
@@ -497,6 +507,7 @@ test_suspend_resume
 test_enable_disable
 test_database_restart
 test_database_change
+test_reconnect
 "
 
 if [ $# -gt 0 ]; then