Skip to content

Commit 4c8e540

Browse files
Andrzej Religadahlerlend
authored andcommitted
Bug#37690477 Router fails to use server that is higher version than its own version.
Fix for bug "Router does not check if server version is higher or not" was part of 9.2 release. It introduced a behavior in the Router where it fails to bootstrap against or use metadata in the runtime from a server that it is a higher version than it's own. The idea was that it can only promise a backward compatibility, not compatibility with the future versions. It was now decided that this behavior is too strict and should be changed. This patch changes the behavior so that a warning is issued but the server is still used for fetching the metadata. Change-Id: I3c71b1ac0b39d36be8c5157695a5671ebba012bd
1 parent bcb4089 commit 4c8e540

File tree

12 files changed

+116
-149
lines changed

12 files changed

+116
-149
lines changed

mysql-test/suite/router/r/metadata_schema_version_compat.result

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ Configure a single REST table object
77
# Registred DB_SCHEMA at path: /svc/basic
88
# Registred DB_OBJECT at path: /svc/basic/tab
99
Make sure the MRS starts the service despite the fact
10-
that minor and patch version is highier than expected
10+
that minor and patch version is higher than expected
1111
DROP SCHEMA basic_schema;
1212
DROP SCHEMA mysql_rest_service_metadata;
1313
DROP ROLE mysql_rest_service_admin;

mysql-test/suite/router/t/metadata_schema_version_compat.test

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# Checks that the Router still accepts metadata when minor and patch version
2-
# is highier than the version it has embedded (knows)
2+
# is higher than the version it has embedded (knows)
33

44
--source include/have_router.inc
55

@@ -52,7 +52,7 @@ AS SELECT $ver_major, $ver_minor, $ver_patch;
5252
--let MRS_CLIENT_ARGS=$MRS_CLIENT --url https://$mrs_host_and_port
5353

5454
echo Make sure the MRS starts the service despite the fact
55-
that minor and patch version is highier than expected;
55+
that minor and patch version is higher than expected;
5656

5757
exec $MRS_CLIENT_ARGS --wait-until-status 60 --path /svc/basic/tab
5858
--display none;

router/src/metadata_cache/include/mysqlrouter/metadata_cache_datatypes.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ inline const std::error_category &metadata_cache_category() noexcept {
7878
case metadata_errc::invalid_cluster_type:
7979
return "unexpected cluster type";
8080
case metadata_errc::outdated_view_id:
81-
return "highier view_id seen";
81+
return "higher view_id seen";
8282
case metadata_errc::schema_version_too_low:
8383
return "metadata schema version not supported";
8484
default:

router/src/metadata_cache/src/cluster_metadata_ar.cc

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -63,11 +63,10 @@ ARClusterMetadata::fetch_cluster_topology(
6363

6464
MySQLSession::Transaction transaction(metadata_connection_.get());
6565

66-
if (!is_server_version_supported(metadata_connection_.get())) {
67-
log_warning("%s - skipping", get_unsupported_server_version_msg(
68-
metadata_connection_.get())
69-
.c_str());
70-
continue;
66+
if (!is_server_version_compatible(metadata_connection_.get())) {
67+
log_warning("%s", get_incompatible_server_version_msg(
68+
metadata_connection_.get())
69+
.c_str());
7170
}
7271

7372
// throws metadata_cache::metadata_error and

router/src/metadata_cache/src/cluster_metadata_gr.cc

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -912,11 +912,10 @@ GRClusterMetadata::fetch_cluster_topology(
912912

913913
MySQLSession::Transaction transaction(metadata_connection_.get());
914914

915-
if (!is_server_version_supported(metadata_connection_.get())) {
916-
log_warning("%s - skipping", get_unsupported_server_version_msg(
917-
metadata_connection_.get())
918-
.c_str());
919-
continue;
915+
if (!is_server_version_compatible(metadata_connection_.get())) {
916+
log_warning("%s", get_incompatible_server_version_msg(
917+
metadata_connection_.get())
918+
.c_str());
920919
}
921920

922921
// throws metadata_cache::metadata_error and

router/src/router/include/mysqlrouter/cluster_metadata.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -118,10 +118,10 @@ bool ROUTER_CLUSTER_EXPORT check_group_replication_online(MySQLSession *mysql);
118118
// throws MySQLSession::Error, std::logic_error, std::out_of_range
119119
bool ROUTER_CLUSTER_EXPORT check_group_has_quorum(MySQLSession *mysql);
120120

121-
bool ROUTER_CLUSTER_EXPORT is_server_version_supported(MySQLSession *mysql);
121+
bool ROUTER_CLUSTER_EXPORT is_server_version_compatible(MySQLSession *mysql);
122122

123123
std::string ROUTER_CLUSTER_EXPORT
124-
get_unsupported_server_version_msg(MySQLSession *mysql);
124+
get_incompatible_server_version_msg(MySQLSession *mysql);
125125

126126
template <size_t N>
127127
bool metadata_schema_version_is_compatible(

router/src/router/src/cluster_metadata.cc

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1421,20 +1421,19 @@ std::string to_string(
14211421
return "drop_all";
14221422
}
14231423

1424-
// We do not support server with version highier than our version
1424+
// We warn when the server version is higher than our version
14251425
// Patch is .99 as we only care about major and minor
1426-
static constexpr const unsigned long max_suported_version_ulong =
1426+
static constexpr const unsigned long max_compatible_version_ulong =
14271427
MYSQL_ROUTER_VERSION_MAJOR * 10000 + MYSQL_ROUTER_VERSION_MINOR * 100 + 99;
14281428

1429-
bool is_server_version_supported(MySQLSession *mysql) {
1430-
return max_suported_version_ulong >= mysql->server_version();
1429+
bool is_server_version_compatible(MySQLSession *mysql) {
1430+
return max_compatible_version_ulong >= mysql->server_version();
14311431
}
14321432

1433-
std::string get_unsupported_server_version_msg(MySQLSession *mysql) {
1434-
return "Unsupported MySQL Server version '" +
1435-
std::to_string(mysql->server_version()) +
1436-
"'. Maximal supported version is '" +
1437-
std::to_string(max_suported_version_ulong) + "'.";
1433+
std::string get_incompatible_server_version_msg(MySQLSession *mysql) {
1434+
return "MySQL Server version '" + std::to_string(mysql->server_version()) +
1435+
"' is higher than the Router version. You should upgrade the Router "
1436+
"to match the MySQL Server version.";
14381437
}
14391438

14401439
} // namespace mysqlrouter

router/src/router/src/config_generator.cc

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -384,8 +384,9 @@ void ConfigGenerator::init(
384384
void ConfigGenerator::check_target(
385385
const std::map<std::string, std::string> &bootstrap_options,
386386
bool allow_no_metadata) {
387-
if (!is_server_version_supported(mysql_)) {
388-
throw std::runtime_error(get_unsupported_server_version_msg(mysql_));
387+
if (!is_server_version_compatible(mysql_)) {
388+
log_warning("WARNING: %s",
389+
get_incompatible_server_version_msg(mysql_).c_str());
389390
}
390391

391392
try {

router/tests/component/test_bootstrap.cc

Lines changed: 24 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -4401,15 +4401,11 @@ TEST_P(CrossExeRouterBootstrapTest, BootstrapRemoveServerAddressesOption) {
44014401
::testing::Not(::testing::HasSubstr("bootstrap_server_addresses")));
44024402
}
44034403

4404-
static constexpr const unsigned long max_supported_version =
4405-
MYSQL_ROUTER_VERSION_MAJOR * 10000 + MYSQL_ROUTER_VERSION_MINOR * 100 + 99;
4406-
44074404
struct ServerCompatTestParam {
44084405
std::string description;
44094406
std::string tracefile;
44104407
std::string server_version;
4411-
bool expect_failure;
4412-
std::string expected_error_msg;
4408+
std::string expected_warning_msg;
44134409
};
44144410

44154411
class CheckServerCompatibilityTest
@@ -4446,15 +4442,13 @@ TEST_P(CheckServerCompatibilityTest, Spec) {
44464442
std::to_string(classic_port),
44474443
"-d", bootstrap_dir.name()};
44484444

4449-
const auto expected_exit_code =
4450-
GetParam().expect_failure ? EXIT_FAILURE : EXIT_SUCCESS;
4451-
auto &router = launch_router_for_bootstrap(cmdline_bs, expected_exit_code);
4452-
check_exit_code(router, expected_exit_code);
4445+
auto &router = launch_router_for_bootstrap(cmdline_bs, EXIT_SUCCESS);
4446+
check_exit_code(router, EXIT_SUCCESS);
44534447

4454-
if (GetParam().expect_failure) {
4448+
if (!GetParam().expected_warning_msg.empty()) {
44554449
const std::string router_console_output = router.get_full_output();
44564450
EXPECT_TRUE(
4457-
pattern_found(router_console_output, GetParam().expected_error_msg))
4451+
pattern_found(router_console_output, GetParam().expected_warning_msg))
44584452
<< router_console_output;
44594453
}
44604454
}
@@ -4468,55 +4462,52 @@ INSTANTIATE_TEST_SUITE_P(
44684462
std::to_string(MYSQL_ROUTER_VERSION_MAJOR) + "." +
44694463
std::to_string(MYSQL_ROUTER_VERSION_MINOR) + "." +
44704464
std::to_string(MYSQL_ROUTER_VERSION_PATCH),
4471-
false, ""},
4465+
""},
44724466
ServerCompatTestParam{
44734467
"Replica Set; Server is the same version as Router - bootstrap OK",
44744468
"bootstrap_ar.js",
44754469
std::to_string(MYSQL_ROUTER_VERSION_MAJOR) + "." +
44764470
std::to_string(MYSQL_ROUTER_VERSION_MINOR) + "." +
44774471
std::to_string(MYSQL_ROUTER_VERSION_PATCH),
4478-
false, ""},
4472+
""},
44794473
ServerCompatTestParam{
4480-
"GR Cluster; Server major version is highier than Router - "
4481-
"bootstrap should fail",
4474+
"GR Cluster; Server major version is higher than Router - "
4475+
"bootstrap should issue a warning",
44824476
"bootstrap_gr.js",
44834477
std::to_string(MYSQL_ROUTER_VERSION_MAJOR + 1) + "." +
44844478
std::to_string(MYSQL_ROUTER_VERSION_MINOR) + "." +
44854479
std::to_string(MYSQL_ROUTER_VERSION_PATCH),
4486-
true,
4487-
"Error: Unsupported MySQL Server version '.*'. Maximal supported "
4488-
"version is '" +
4489-
std::to_string(max_supported_version) + "'."},
4480+
"WARNING: MySQL Server version .* is higher than the Router "
4481+
"version. You should upgrade the Router to match the MySQL Server "
4482+
"version."},
44904483
ServerCompatTestParam{
4491-
"GR Cluster; Server minor version is highier than Router - "
4492-
"bootstrap should fail",
4484+
"GR Cluster; Server minor version is higher than Router - "
4485+
"bootstrap should issue a warning",
44934486
"bootstrap_gr.js",
44944487
std::to_string(MYSQL_ROUTER_VERSION_MAJOR) + "." +
44954488
std::to_string(MYSQL_ROUTER_VERSION_MINOR + 1) + "." +
44964489
std::to_string(MYSQL_ROUTER_VERSION_PATCH),
4497-
true,
4498-
"Error: Unsupported MySQL Server version '.*'. Maximal supported "
4499-
"version is '" +
4500-
std::to_string(max_supported_version) + "'."},
4490+
"WARNING: MySQL Server version .* is higher than the Router "
4491+
"version. You should upgrade the Router to match the MySQL Server "
4492+
"version."},
45014493
ServerCompatTestParam{
4502-
"GR Cluster; Server patch version is highier than Router - "
4494+
"GR Cluster; Server patch version is higher than Router - "
45034495
"bootstrap OK",
45044496
"bootstrap_gr.js",
45054497
std::to_string(MYSQL_ROUTER_VERSION_MAJOR) + "." +
45064498
std::to_string(MYSQL_ROUTER_VERSION_MINOR) + "." +
45074499
std::to_string(MYSQL_ROUTER_VERSION_PATCH + 1),
4508-
false, ""},
4500+
""},
45094501
ServerCompatTestParam{
4510-
"Replica Set; Server major version is highier than Router - "
4511-
"bootstrap should fail",
4502+
"Replica Set; Server major version is higher than Router - "
4503+
"bootstrap should issue a warning",
45124504
"bootstrap_ar.js",
45134505
std::to_string(MYSQL_ROUTER_VERSION_MAJOR) + "." +
45144506
std::to_string(MYSQL_ROUTER_VERSION_MINOR + 1) + "." +
45154507
std::to_string(MYSQL_ROUTER_VERSION_PATCH),
4516-
true,
4517-
"Error: Unsupported MySQL Server version '.*'. Maximal supported "
4518-
"version is '" +
4519-
std::to_string(max_supported_version) + "'."}));
4508+
"WARNING: MySQL Server version .* is higher than the Router "
4509+
"version. You should upgrade the Router to match the MySQL Server "
4510+
"version."}));
45204511

45214512
TEST_P(CrossExeRouterBootstrapTest, LocalClusterFromClusterName) {
45224513
// launch our Cluster mock

router/tests/component/test_bootstrap_clusterset.cc

Lines changed: 18 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1172,14 +1172,10 @@ TEST_F(RouterClusterSetBootstrapTest, ConfigExposedInMetadata) {
11721172
public_configuration_defaults_in_md.c_str());
11731173
}
11741174

1175-
static constexpr const unsigned long max_supported_version =
1176-
MYSQL_ROUTER_VERSION_MAJOR * 10000 + MYSQL_ROUTER_VERSION_MINOR * 100 + 99;
1177-
11781175
struct ServerCompatTestParam {
11791176
std::string description;
11801177
std::string server_version;
1181-
bool expect_failure;
1182-
std::string expected_error_msg;
1178+
std::string expected_warning_msg;
11831179
};
11841180

11851181
class CheckServerCompatibilityTest
@@ -1207,16 +1203,13 @@ TEST_P(CheckServerCompatibilityTest, Spec) {
12071203
std::to_string(cs_options.topology.clusters[0].nodes[0].classic_port),
12081204
"-d", bootstrap_directory.name()};
12091205

1210-
const auto expected_exit_code =
1211-
GetParam().expect_failure ? EXIT_FAILURE : EXIT_SUCCESS;
1212-
auto &router =
1213-
launch_router_for_bootstrap(bootstrap_params, expected_exit_code);
1214-
check_exit_code(router, expected_exit_code);
1206+
auto &router = launch_router_for_bootstrap(bootstrap_params, EXIT_SUCCESS);
1207+
check_exit_code(router, EXIT_SUCCESS);
12151208

1216-
if (GetParam().expect_failure) {
1209+
if (!GetParam().expected_warning_msg.empty()) {
12171210
const std::string router_console_output = router.get_full_output();
12181211
EXPECT_TRUE(
1219-
pattern_found(router_console_output, GetParam().expected_error_msg))
1212+
pattern_found(router_console_output, GetParam().expected_warning_msg))
12201213
<< router_console_output;
12211214
}
12221215
}
@@ -1229,33 +1222,31 @@ INSTANTIATE_TEST_SUITE_P(
12291222
std::to_string(MYSQL_ROUTER_VERSION_MAJOR) + "." +
12301223
std::to_string(MYSQL_ROUTER_VERSION_MINOR) + "." +
12311224
std::to_string(MYSQL_ROUTER_VERSION_PATCH),
1232-
false, ""},
1225+
""},
12331226
ServerCompatTestParam{
1234-
"Server major version is highier than Router - bootstrap should "
1235-
"fail",
1227+
"Server major version is higher than Router - bootstrap should "
1228+
"issue a warning",
12361229
std::to_string(MYSQL_ROUTER_VERSION_MAJOR + 1) + "." +
12371230
std::to_string(MYSQL_ROUTER_VERSION_MINOR) + "." +
12381231
std::to_string(MYSQL_ROUTER_VERSION_PATCH),
1239-
true,
1240-
"Error: Unsupported MySQL Server version '.*'. Maximal supported "
1241-
"version is '" +
1242-
std::to_string(max_supported_version) + "'."},
1232+
"WARNING: MySQL Server version .* is higher than the Router "
1233+
"version. You should upgrade the Router to match the MySQL Server "
1234+
"version."},
12431235
ServerCompatTestParam{
1244-
"Server minor version is highier than Router - bootstrap should "
1245-
"fail",
1236+
"Server minor version is higher than Router - bootstrap should "
1237+
"issue a warning",
12461238
std::to_string(MYSQL_ROUTER_VERSION_MAJOR) + "." +
12471239
std::to_string(MYSQL_ROUTER_VERSION_MINOR + 1) + "." +
12481240
std::to_string(MYSQL_ROUTER_VERSION_PATCH),
1249-
true,
1250-
"Error: Unsupported MySQL Server version '.*'. Maximal supported "
1251-
"version is '" +
1252-
std::to_string(max_supported_version) + "'."},
1241+
"WARNING: MySQL Server version .* is higher than the Router "
1242+
"version. You should upgrade the Router to match the MySQL Server "
1243+
"version."},
12531244
ServerCompatTestParam{
1254-
"Server patch version is highier than Router - bootstrap OK",
1245+
"Server patch version is higher than Router - bootstrap OK",
12551246
std::to_string(MYSQL_ROUTER_VERSION_MAJOR) + "." +
12561247
std::to_string(MYSQL_ROUTER_VERSION_MINOR) + "." +
12571248
std::to_string(MYSQL_ROUTER_VERSION_PATCH + 1),
1258-
false, ""}));
1249+
""}));
12591250

12601251
struct LocalClusterTestParams {
12611252
std::string expected_local_cluster;

0 commit comments

Comments
 (0)