Fix bug with load balance node id info on shmem
authorTatsuo Ishii <ishii@postgresql.org>
Wed, 15 Jun 2016 07:34:51 +0000 (16:34 +0900)
committerTatsuo Ishii <ishii@postgresql.org>
Wed, 15 Jun 2016 07:55:41 +0000 (16:55 +0900)
There are few places where the load balance node was mistakenly put on
wrong place. It should be placed on:
ConnectionInfo *con_info[child id, connection pool_id, backend id].load_balancing_node].
In fact it was placed on:
*con_info[child id, connection pool_id, 0].load_balancing_node].

As long as the backend id in question is 0, it is ok. However while
testing pgpool-II 3.6's enhancement regarding failover, if primary
node is 1 (which is the load balance node) and standby is 0, a client
connecting to node 1 is disconnected when failover happens on node
0. This is unexpected and the bug was revealed.

It seems the bug was there since long time ago but it had not found
until today by the reason above.

src/context/pool_session_context.c
src/protocol/pool_process_query.c

index b22fdb89691b0d01872d5cc5aa5870d0e5b445a6..0afd66c6bfd60870a1e450be1a580ffdb5f2409f 100644 (file)
@@ -6,7 +6,7 @@
  * pgpool: a language independent connection pool server for PostgreSQL 
  * written by Tatsuo Ishii
  *
- * Copyright (c) 2003-2011     PgPool Global Development Group
+ * Copyright (c) 2003-2016     PgPool Global Development Group
  *
  * Permission to use, copy, modify, and distribute this software and
  * its documentation for any purpose and without fee is hereby
@@ -44,6 +44,7 @@ void pool_init_session_context(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *
        session_context = &session_context_d;
        ProcessInfo *process_info;
        int node_id;
+       int i;
 
        /* Get Process context */
        session_context->process_context = pool_get_process_context();
@@ -88,12 +89,17 @@ void pool_init_session_context(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *
                node_id = STREAM? PRIMARY_NODE_ID: MASTER_NODE_ID;
        }
 
-       session_context->load_balance_node_id =
-               process_info->connection_info->load_balancing_node = node_id;
+       session_context->load_balance_node_id = node_id;
+
+       for (i=0;i<NUM_BACKENDS;i++)
+       {
+               pool_coninfo(session_context->process_context->proc_id,
+                                        pool_pool_index(), i)->load_balancing_node = node_id;
+       }
 
        ereport(DEBUG1,
                        (errmsg("initializing session context"),
-                        errdetail("selected load balancing node: %d", backend->info->load_balancing_node)));
+                        errdetail("selected load balancing node: %d", node_id)));
 
        /* Unset query is in progress */
        pool_unset_query_in_progress();
index 5aac18cf5d004c1ef2a5a875ece7e38298eecc54..90f30160956572fadb5b876c7f23fcb6c73847f1 100644 (file)
@@ -4672,7 +4672,17 @@ SELECT_RETRY:
                BACKEND_INFO(backend->info->load_balancing_node).backend_status == CON_DOWN)
        {
                /* select load balancing node */
-               backend->info->load_balancing_node = select_load_balancing_node();
+               POOL_SESSION_CONTEXT *session_context;
+               int node_id;
+
+               session_context = pool_get_session_context(false);
+               node_id = select_load_balancing_node();
+
+               for (i=0;i<NUM_BACKENDS;i++)
+               {
+                       pool_coninfo(session_context->process_context->proc_id,
+                                                pool_pool_index(), i)->load_balancing_node = node_id;
+               }
        }
 
        for (i=0;i<NUM_BACKENDS;i++)