From 5ee9b7477010d7334c2e1ab7595d07435fdcb5ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markus=20M=C3=A4kel=C3=A4?= Date: Tue, 26 Mar 2019 23:44:37 +0200 Subject: [PATCH] Fix readwritesplit server selection If a server with zero weight was chosen as the only candidate, it was possible that the starting minimum value was smaller than the server score. This would mean that a candidate wouldn't be chosen if the score was too high. To preven this, the values are capped to a value smaller than the initial minimum score. --- .../routing/readwritesplit/rwsplit_select_backends.cc | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/server/modules/routing/readwritesplit/rwsplit_select_backends.cc b/server/modules/routing/readwritesplit/rwsplit_select_backends.cc index a7dfc8131..082e2736a 100644 --- a/server/modules/routing/readwritesplit/rwsplit_select_backends.cc +++ b/server/modules/routing/readwritesplit/rwsplit_select_backends.cc @@ -53,6 +53,7 @@ static bool valid_for_slave(const RWBackend* backend, const RWBackend* master) PRWBackends::iterator best_score(PRWBackends& sBackends, std::function server_score) { + const double max_score = std::nexttoward(std::numeric_limits::max(), 0.0); double min {std::numeric_limits::max()}; auto best = sBackends.end(); for (auto ite = sBackends.begin(); ite != sBackends.end(); ++ite) @@ -65,6 +66,13 @@ PRWBackends::iterator best_score(PRWBackends& sBackends, score = (score + 5.0) * 1.5; } + if (score > max_score) + { + // Cap values to a maximum value. This guarantees that we choose a server from the set of + // available candidates. + score = max_score; + } + if (min > score) { min = score; @@ -72,6 +80,9 @@ PRWBackends::iterator best_score(PRWBackends& sBackends, } } + mxb_assert_message(best != sBackends.end() || sBackends.empty(), + "A candidate must be chosen if we have candidates"); + return best; }