diff --git a/server/modules/routing/readwritesplit/readwritesplit.c b/server/modules/routing/readwritesplit/readwritesplit.c index 74bde276f..2a7cb5d9e 100644 --- a/server/modules/routing/readwritesplit/readwritesplit.c +++ b/server/modules/routing/readwritesplit/readwritesplit.c @@ -4059,8 +4059,16 @@ return_rc: * Suppress redundant OK packets sent by backends. * * The first OK packet is replied to the client. - * Return true if succeed, false is returned if router session was closed or - * if execute_sescmd_in_backend failed. + * + * @param router_cli_ses Client's router session pointer + * @param querybuf GWBUF including the query to be routed + * @param inst Router instance + * @param packet_type Type of MySQL packet + * @param qtype Query type from query_classifier + * + * @return True if at least one backend is used and routing succeed to all + * backends being used, otherwise false. + * */ static bool route_session_write( ROUTER_CLIENT_SES* router_cli_ses, @@ -4073,11 +4081,18 @@ static bool route_session_write( rses_property_t* prop; backend_ref_t* backend_ref; int i; + int max_nslaves; + int nbackends; + int nsucc; LOGIF(LT, (skygw_log_write( LOGFILE_TRACE, "Session write, routing to all servers."))); - + /** Maximum number of slaves in this router client session */ + max_nslaves = rses_get_max_slavecount(router_cli_ses, + router_cli_ses->rses_nbackends); + nsucc = 0; + nbackends = 0; backend_ref = router_cli_ses->rses_backend_ref; /** @@ -4091,13 +4106,10 @@ static bool route_session_write( packet_type == MYSQL_COM_STMT_CLOSE) { int rc; - - succp = true; - - /** Lock router session */ + + /** Lock router session */ if (!rses_begin_locked_router_action(router_cli_ses)) { - succp = false; goto return_succp; } @@ -4119,12 +4131,11 @@ static bool route_session_write( if (BREF_IS_IN_USE((&backend_ref[i]))) { - rc = dcb->func.write(dcb, gwbuf_clone(querybuf)); - - if (rc != 1) - { - succp = false; - } + nbackends += 1; + if ((rc = dcb->func.write(dcb, gwbuf_clone(querybuf))) == 1) + { + nsucc += 1; + } } } rses_end_locked_router_action(router_cli_ses); @@ -4134,13 +4145,16 @@ static bool route_session_write( /** Lock router session */ if (!rses_begin_locked_router_action(router_cli_ses)) { - succp = false; goto return_succp; } if (router_cli_ses->rses_nbackends <= 0) { - succp = false; + LOGIF(LT, (skygw_log_write( + LOGFILE_TRACE, + "Router session doesn't have any backends in use. " + "Routing failed. <"))); + goto return_succp; } /** @@ -4160,6 +4174,8 @@ static bool route_session_write( { sescmd_cursor_t* scur; + nbackends += 1; + if (LOG_IS_ENABLED(LOGFILE_TRACE)) { LOGIF(LT, (skygw_log_write( @@ -4187,8 +4203,7 @@ static bool route_session_write( */ if (sescmd_cursor_is_active(scur)) { - succp = true; - + nsucc += 1; LOGIF(LT, (skygw_log_write( LOGFILE_TRACE, "Backend %s:%d already executing sescmd.", @@ -4197,10 +4212,12 @@ static bool route_session_write( } else { - succp = execute_sescmd_in_backend(&backend_ref[i]); - - if (!succp) - { + if (execute_sescmd_in_backend(&backend_ref[i])) + { + nsucc += 1; + } + else + { LOGIF(LE, (skygw_log_write_flush( LOGFILE_ERROR, "Error : Failed to execute session " @@ -4210,18 +4227,20 @@ static bool route_session_write( } } } - else - { - succp = false; - } } /** Unlock router session */ rses_end_locked_router_action(router_cli_ses); return_succp: + /** + * Routing must succeed to all backends that are used. + * There must be at leas one and at most max_nslaves+1 backends. + */ + succp = (nbackends > 0 && nsucc == nbackends && nbackends <= max_nslaves+1); return succp; } + #if defined(NOT_USED) static bool router_option_configured(