pgpool2.git / summary / log / commit / refs

commit    da2b555e75444b50a949f181dbfeeabb3bc0a076
Author:   Tatsuo Ishii <ishii@sraoss.co.jp>
Date:     Tue Apr 02 10:30:27 2024 +0000

    Fix errors/hung up when load_balance_mode is off.
    
    Commit: 3f3c1656 Fix statement_level_load_balance with BEGIN etc.
    
    brought errors/hung up when load_balance_mode is off, primary node id
    is not 0 and queries are BEGIN etc.
    
    pool_setall_node_to_be_sent() checked if the node is primary. If not,
    just returned with empty where_to_send map which makes
    set_vrtual_main_node() not to set
    query_context->virtual_main_node_id. As a result, MAIN_NODE macro
    (it's actually pool_virtual_main_db_node_id()) returns
    REAL_MAIN_NODE_ID, which is 0 if node 0 is alive (this should have
    been primary node id).
    
    Following simple test reveals the bug.
    
    (1) create a two-node cluster using pgpool_setup
    
    (2) shutdown node 0 and recover node 1 (pcp_recovery_node 0). This
    makes node 0 to be standby, node 1 to be primary.
    
    (3) add followings to pgpool.conf and restart whole cluster.
    
    load_balance_mode = off
    backend_weight1 = 0
    
    (4) type "begin" from psql. It gets stuck.
    
    Bug found and analyzed by Emond Papegaaij.
    Discussion: https://www.pgpool.net/pipermail/pgpool-general/2024-March/009113.html
    Backpatch-through: v4.1


src/context/pool_query_context.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/context/pool_query_context.c b/src/context/pool_query_context.c index 3381fb42a..eea355425 100644 --- a/src/context/pool_query_context.c +++ b/src/context/pool_query_context.c @@ -244,20 +244,23 @@ pool_setall_node_to_be_sent(POOL_QUERY_CONTEXT * query_context) { /* * If load balance mode is disabled, only send to the primary node. - * or send to the main node if primary node does not exist. + * If primary node does not exist, send to the main node. */ if (!pool_config->load_balance_mode) { if (i == PRIMARY_NODE_ID || (PRIMARY_NODE_ID < 0 && MAIN_NODE_ID == i)) + { query_context->where_to_send[i] = true; - break; + break; + } + continue; } else /* * If the node is not primary node nor load balance node, - * there's no point to send query except statement load - * balance is enabled. + * there's no point to send query except statement level + * load balance is enabled. */ if (!pool_config->statement_level_load_balance && i != PRIMARY_NODE_ID && i != sc->load_balance_node_id) [parent: c28e448d300a]