pgpool2.git / summary / log / commit / refs

commit    6e7a68c1c73d8a9a7847ab73cb3cecdfbed0f90c
Author:   Tatsuo Ishii <ishii@postgresql.org>
Date:     Thu Apr 05 08:11:36 2018 +0000

    Fix pgpool child process segfault when ALWAYS_MASTER is on.
    
    If following conditions are all met pgpool child segfaults:
    
    1) Streaming replication mode.
    
    2) fail_over_on_backend_error is off.
    
    3) ALWAYS_MASTER flag is set to the master (writer) node.
    
    4) pgpool_status file indicates that the node mentioned in #3 is in
       down status.
    
    What happens here is,
    
    1) find_primary_node() returns node id 0 without checking the status
       of node 0 since ALWAYS_MASTER is set. It's remembered as the
       primary node id. The node id is stored in Req_info->primary_node_id.
    
    2) The connection to backend 0 is not created since pgpool_status says
       it's in down status.
    
    3) upon starting of session, select_load_balancing_node () is called
       and it tries to determine the database name from client's start up
       packet.
    
    4) Since MASTER_CONNECTION macro points to the PRIMARY_NODE,
       MASTER_CONNECTION(ses->backend) is NULL and it results in a segfault.
    
    The fix is, to change PRIMARY_NODE_ID macro so that it returns
    REAL_MASTER_NODE_ID (that is the youngest node id which is alive) if
    the node id in Req_info->primary_node_id is in down status. This can
    be checked using VALID_BACKEND_RAW macro.
    
    VALID_BACKEND macro cannot be used here because it calls
    pool_is_node_to_be_sent_in_current_query() inside. Problem is, when a
    query is about to processed, pool_is_query_in_progress() is already
    set but pool_is_node_to_be_sent() could return false because
    where_to_send member in the query context may not be is set yet
    (that's the cause of the enbug in Pgpool-II 3.7.2).
    
    So we have the "true" primary node id in Req_info->primary_node_id,
    and "fake" primary node id returned by PRIMARY_NODE_ID macro.
    
    See [pgpool-hackers: 2687] and [pgpool-general: 5881] Pgpool-3.7.1
    segmentation fault for more details.
    
    Since ALWAYS_MASTER flag was introduced in 3.7, back pached to 3.7
    only.
    Per bug report from Philip Champon.


src/include/pool.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/include/pool.h b/src/include/pool.h index 48cd82909..f87995cd0 100644 --- a/src/include/pool.h +++ b/src/include/pool.h @@ -333,7 +333,7 @@ extern int my_master_node_id; * mode or there's no primary node, this macro returns * REAL_MASTER_NODE_ID. */ -#define PRIMARY_NODE_ID (Req_info->primary_node_id >=0?\ +#define PRIMARY_NODE_ID (Req_info->primary_node_id >=0 && VALID_BACKEND_RAW(Req_info->primary_node_id) ? \ Req_info->primary_node_id:REAL_MASTER_NODE_ID) #define IS_PRIMARY_NODE_ID(node_id) (node_id == PRIMARY_NODE_ID) [parent: e0088af745e7]