Fixing an issue in the handling of pg_terminate_backend()
authorMuhammad Usama <m.usama@gmail.com>
Wed, 25 Oct 2017 15:22:38 +0000 (20:22 +0500)
committerMuhammad Usama <m.usama@gmail.com>
Wed, 25 Oct 2017 15:22:38 +0000 (20:22 +0500)
In some cases pg_terminate_backend() can cause failover even when
the call is properly issued through Pgpool-II.

This problem is, we do not set of the swallow_termination flag when the
pg_terminate_backend refers to the backend connection of the child
process on which the pg_terminate_backend() was issued.
This was due to the wrong assumption, that we always get the proper
socket close indication when backend to terminate is the same on which
pg_terminate_backend() is issued, Apparently this is not the case,
and PostgreSQL backend can still get abruptly killed even when it is
asked to terminate itself, And this abrupt termination of the connection
makes the Pgpool-II to consider it as a backend failure.

The solution to this is to always set the swallow_termination, even when the
pg_terminate_backend is referring to the local backend connection.

src/context/pool_process_context.c
src/include/context/pool_process_context.h
src/protocol/pool_proto_modules.c

index f765f4d3608d67b93fb5a9f4bd2e2c53027ff0c4..25de937b827d7b7dafa9e972ea78022977b2e61d 100644 (file)
@@ -238,31 +238,6 @@ ConnectionInfo* pool_coninfo_backend_pid(int backend_pid, int* backend_node_id)
        return NULL;
 }
 
-/*
- * returns true if the conInfo object belongs to the current child process
- */
-bool pool_is_my_coninfo(ConnectionInfo* connInfo)
-{
-       int pool;
-       ProcessInfo *pi = pool_get_my_process_info();
-       for (pool = 0; pool < pool_config->max_pool; pool++)
-       {
-               int backend_id;
-               for (backend_id = 0; backend_id < NUM_BACKENDS; backend_id++)
-               {
-                       int poolBE = pool*MAX_NUM_BACKENDS+backend_id;
-                       ConnectionInfo* cInfo = &pi->connection_info[poolBE];
-                       if (cInfo == connInfo)
-                       {
-                               ereport(DEBUG1,
-                                               (errmsg("connection Info object is local")));
-                               return true;
-                       }
-               }
-       }
-       return false;
-}
-
 /*
  * sets the flag to mark that the connection will be terminated by the
  * backend and it should not be considered as a backend node failure.
index 01fa8e49133b59f63d403e5f9c28854fdf1671f8..2e7863b0c77b568b0f149be513fbbbd7422f1ac4 100644 (file)
@@ -65,7 +65,6 @@ extern void pool_coninfo_set_frontend_connected(int proc_id, int pool_index);
 extern void pool_coninfo_unset_frontend_connected(int proc_id, int pool_index);
 
 extern ConnectionInfo* pool_coninfo_backend_pid(int backend_pid, int* backend_node_id);
-extern bool pool_is_my_coninfo(ConnectionInfo* connInfo);
 extern void pool_set_connection_will_be_terminated(ConnectionInfo* connInfo);
 extern void pool_unset_connection_will_be_terminated(ConnectionInfo* connInfo);
 
index 4de769d92d95de086d979a6f516df14d1a7c176f..25b7b3635e05d4449a797bc887b75966bd5cafdf 100644 (file)
@@ -146,14 +146,7 @@ static bool process_pg_terminate_backend_func(POOL_QUERY_CONTEXT *query_context)
                        (errmsg("found the pg_terminate_backend request for backend pid:%d on backend node:%d",backend_pid,backend_node),
                                 errdetail("setting the connection flag")));
 
-               if (pool_is_my_coninfo(conn)){
-                       ereport(LOG,
-                               (errmsg("pg_terminate_backend refer to the current child process connection"),
-                                        errdetail("setting the connection flag not required")));
-               }
-               else{
-                       pool_set_connection_will_be_terminated(conn);
-               }
+               pool_set_connection_will_be_terminated(conn);
                /* It was the pg_terminate_backend call so send the query to appropriate backend */
                query_context->pg_terminate_backend_conn = conn;
                pool_force_query_node_to_backend(query_context, backend_node);