diff --git a/mysql-test/suite/galera/r/galera_var_wsrep_start_position.result b/mysql-test/suite/galera/r/galera_var_wsrep_start_position.result index fe0bdaa404f44..86fb941a71878 100644 --- a/mysql-test/suite/galera/r/galera_var_wsrep_start_position.result +++ b/mysql-test/suite/galera/r/galera_var_wsrep_start_position.result @@ -99,6 +99,71 @@ ERROR 42000: Variable 'wsrep_start_position' can't be set to the value of 'junk' SELECT @@global.wsrep_start_position; @@global.wsrep_start_position 00000000-0000-0000-0000-000000000000:-1 +SET @@global.wsrep_start_position='12345678'; +ERROR 42000: Variable 'wsrep_start_position' can't be set to the value of '12345678' +SHOW WARNINGS; +Level Code Message +Warning 1231 wsrep_start_position incorrect '12345678', too short +Error 1231 Variable 'wsrep_start_position' can't be set to the value of '12345678' +SET @@global.wsrep_start_position='12345678-1234 1234-1234-123456789012!a'; +ERROR 42000: Variable 'wsrep_start_position' can't be set to the value of '12345678-1234 1234-1234-123456789012!a' +SHOW WARNINGS; +Level Code Message +Warning 1231 wsrep_start_position incorrect '12345678-1234 1234-1234-123456789012!a', wrong uuid +Error 1231 Variable 'wsrep_start_position' can't be set to the value of '12345678-1234 1234-1234-123456789012!a' +SET @@global.wsrep_start_position='12345678-1234-1234-1234-123456789012!a'; +ERROR 42000: Variable 'wsrep_start_position' can't be set to the value of '12345678-1234-1234-1234-123456789012!a' +SHOW WARNINGS; +Level Code Message +Warning 1231 wsrep_start_position incorrect '12345678-1234-1234-1234-123456789012!a', separator mising after UUID +Error 1231 Variable 'wsrep_start_position' can't be set to the value of '12345678-1234-1234-1234-123456789012!a' +SET @@global.wsrep_start_position='12345678-1234-1234-1234-123456789012:-100'; +ERROR 42000: Variable 'wsrep_start_position' can't be set to the value of '12345678-1234-1234-1234-123456789012:-100' +SHOW WARNINGS; +Level Code Message +Warning 1231 wsrep_start_position incorrect '', seqno incorrect +Error 1231 Variable 'wsrep_start_position' can't be set to the value of '12345678-1234-1234-1234-123456789012:-100' +SET @@global.wsrep_start_position='12345678-1234-1234-1234-123456789012:A'; +ERROR 42000: Variable 'wsrep_start_position' can't be set to the value of '12345678-1234-1234-1234-123456789012:A' +SHOW WARNINGS; +Level Code Message +Warning 1231 wsrep_start_position incorrect 'A', incorrect format +Error 1231 Variable 'wsrep_start_position' can't be set to the value of '12345678-1234-1234-1234-123456789012:A' +SET @@global.wsrep_start_position='12345678-1234-1234-1234-123456789012:100:'; +ERROR 42000: Variable 'wsrep_start_position' can't be set to the value of '12345678-1234-1234-1234-123456789012:100:' +SHOW WARNINGS; +Level Code Message +Warning 1231 wsrep_start_position incorrect ':', incorrect format +Error 1231 Variable 'wsrep_start_position' can't be set to the value of '12345678-1234-1234-1234-123456789012:100:' +SET @@global.wsrep_start_position='12345678-1234-1234-1234-123456789012:100,1B'; +ERROR 42000: Variable 'wsrep_start_position' can't be set to the value of '12345678-1234-1234-1234-123456789012:100,1B' +SHOW WARNINGS; +Level Code Message +Warning 1231 wsrep_start_position incorrect 'B', domain incorrect +Error 1231 Variable 'wsrep_start_position' can't be set to the value of '12345678-1234-1234-1234-123456789012:100,1B' +SET @@global.wsrep_start_position='12345678-1234-1234-1234-123456789012:100,1-1C'; +ERROR 42000: Variable 'wsrep_start_position' can't be set to the value of '12345678-1234-1234-1234-123456789012:100,1-1C' +SHOW WARNINGS; +Level Code Message +Warning 1231 wsrep_start_position incorrect 'C', server incorrect +Error 1231 Variable 'wsrep_start_position' can't be set to the value of '12345678-1234-1234-1234-123456789012:100,1-1C' +SET @@global.wsrep_start_position='12345678-1234-1234-1234-123456789012:100,1-1-20B'; +ERROR 42000: Variable 'wsrep_start_position' can't be set to the value of '12345678-1234-1234-1234-123456789012:100,1-1-20B' +SHOW WARNINGS; +Level Code Message +Warning 1231 wsrep_start_position incorrect 'B', incorrect format +Error 1231 Variable 'wsrep_start_position' can't be set to the value of '12345678-1234-1234-1234-123456789012:100,1-1-20B' +SET @@global.wsrep_start_position='12345678-1234-1234-1234-123456789012:100,1-1-20/abcdefghijklmn'; +ERROR 42000: Variable 'wsrep_start_position' can't be set to the value of '12345678-1234-1234-1234-123456789012:100,1-1-20/abcdefghijklmn' +SHOW WARNINGS; +Level Code Message +Warning 1231 wsrep_start_position incorrect 'abcdefghijklmn', local_seqno incorrect +Error 1231 Variable 'wsrep_start_position' can't be set to the value of '12345678-1234-1234-1234-123456789012:100,1-1-20/abcdefghijklmn' +SET @@global.wsrep_start_position='64de8141-7bf8-11f0-a5e1-2f107ecf09fa:8410/8502/11/57df8fe9-7bf8-11f0-83b8-00e04ca2f8fe'; +ERROR 42000: Variable 'wsrep_start_position' can't be set to the value of '64de8141-7bf8-11f0-a5e1-2f107ecf09fa:8410/8502/11/57df8fe9-7bf8-11f0-83b8-00e04ca2f8fe' +SHOW WARNINGS; +Level Code Message +Error 1231 Variable 'wsrep_start_position' can't be set to the value of '64de8141-7bf8-11f0-a5e1-2f107ecf09fa:8410/8502/11/57df8fe9-7bf8-11f0-83b8-00e04ca2f8fe' # restore the initial value SET @@global.wsrep_start_position = @wsrep_start_position_global_saved; diff --git a/mysql-test/suite/galera/t/galera_var_wsrep_start_position.test b/mysql-test/suite/galera/t/galera_var_wsrep_start_position.test index 24e2e0336764d..3bcd6b840d2b8 100644 --- a/mysql-test/suite/galera/t/galera_var_wsrep_start_position.test +++ b/mysql-test/suite/galera/t/galera_var_wsrep_start_position.test @@ -69,6 +69,51 @@ SELECT @@global.wsrep_start_position; SET @@global.wsrep_start_position='junk'; SELECT @@global.wsrep_start_position; +# too short +--error ER_WRONG_VALUE_FOR_VAR +SET @@global.wsrep_start_position='12345678'; +SHOW WARNINGS; +# wrong uuid +--error ER_WRONG_VALUE_FOR_VAR +SET @@global.wsrep_start_position='12345678-1234 1234-1234-123456789012!a'; +SHOW WARNINGS; +# wrong separator +--error ER_WRONG_VALUE_FOR_VAR +SET @@global.wsrep_start_position='12345678-1234-1234-1234-123456789012!a'; +SHOW WARNINGS; +# wrong seqno 1 +--error ER_WRONG_VALUE_FOR_VAR +SET @@global.wsrep_start_position='12345678-1234-1234-1234-123456789012:-100'; +SHOW WARNINGS; +# wrong seqno 2 +--error ER_WRONG_VALUE_FOR_VAR +SET @@global.wsrep_start_position='12345678-1234-1234-1234-123456789012:A'; +SHOW WARNINGS; +# wrong separator for gtid +--error ER_WRONG_VALUE_FOR_VAR +SET @@global.wsrep_start_position='12345678-1234-1234-1234-123456789012:100:'; +SHOW WARNINGS; +# domain wrong +--error ER_WRONG_VALUE_FOR_VAR +SET @@global.wsrep_start_position='12345678-1234-1234-1234-123456789012:100,1B'; +SHOW WARNINGS; +# server wrong +--error ER_WRONG_VALUE_FOR_VAR +SET @@global.wsrep_start_position='12345678-1234-1234-1234-123456789012:100,1-1C'; +SHOW WARNINGS; +# remaining string was not seqno +--error ER_WRONG_VALUE_FOR_VAR +SET @@global.wsrep_start_position='12345678-1234-1234-1234-123456789012:100,1-1-20B'; +SHOW WARNINGS; +# format ok but wrong value +--error ER_WRONG_VALUE_FOR_VAR +SET @@global.wsrep_start_position='12345678-1234-1234-1234-123456789012:100,1-1-20/abcdefghijklmn'; +SHOW WARNINGS; +# correct format but wrong position +--error ER_WRONG_VALUE_FOR_VAR +SET @@global.wsrep_start_position='64de8141-7bf8-11f0-a5e1-2f107ecf09fa:8410/8502/11/57df8fe9-7bf8-11f0-83b8-00e04ca2f8fe'; +SHOW WARNINGS; + --echo --echo # restore the initial value SET @@global.wsrep_start_position = @wsrep_start_position_global_saved; diff --git a/sql/wsrep_var.cc b/sql/wsrep_var.cc index 3d7b7941d2e23..6a1f945ad454c 100644 --- a/sql/wsrep_var.cc +++ b/sql/wsrep_var.cc @@ -1,4 +1,4 @@ -/* Copyright 2008-2023 Codership Oy +/* Copyright 2008-2025 Codership Oy This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -232,7 +232,7 @@ static T parse_value(char** startptr, char** endptr) false Pass */ static -bool wsrep_start_position_verify (const char* start_str) +bool wsrep_start_position_verify (THD* thd, const char* start_str) { size_t start_len; wsrep_uuid_t uuid; @@ -241,19 +241,36 @@ bool wsrep_start_position_verify (const char* start_str) // Check whether it has minimum acceptable length. start_len= strlen (start_str); if (start_len < 34) + { + push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN, + ER_WRONG_VALUE_FOR_VAR, + "wsrep_start_position incorrect '%s', too short", + start_str); return true; - + } /* Parse the input to check whether UUID length is acceptable and seqno has been provided. */ uuid_len= wsrep_uuid_scan (start_str, start_len, &uuid); if (uuid_len < 0 || (start_len - uuid_len) < 2) + { + push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN, + ER_WRONG_VALUE_FOR_VAR, + "wsrep_start_position incorrect '%s', wrong uuid", + start_str); return true; - + } // Separator must follow the UUID. if (start_str[uuid_len] != ':') + { + push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN, + ER_WRONG_VALUE_FOR_VAR, + "wsrep_start_position incorrect '%s'" + ", separator mising after UUID", + start_str); return true; + } char* endptr; char* startptr= (char *)start_str + uuid_len + 1; @@ -261,7 +278,14 @@ bool wsrep_start_position_verify (const char* start_str) // Do not allow seqno < -1 if (seqno < -1) + { + push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN, + ER_WRONG_VALUE_FOR_VAR, + "wsrep_start_position incorrect '%s'" + ", seqno incorrect", + startptr); return true; + } // Start parsing native GTID part if (*startptr == ',') @@ -269,19 +293,61 @@ bool wsrep_start_position_verify (const char* start_str) startptr++; uint32_t domain __attribute__((unused)) (parse_value(&startptr, &endptr)); - if (*endptr != '-') return true; + if (*endptr != '-') + { + push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN, + ER_WRONG_VALUE_FOR_VAR, + "wsrep_start_position incorrect '%s'" + ", domain incorrect", + endptr); + return true; + } startptr++; uint32_t server __attribute__((unused)) (parse_value(&startptr, &endptr)); - if (*endptr != '-') return true; + if (*endptr != '-') + { + push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN, + ER_WRONG_VALUE_FOR_VAR, + "wsrep_start_position incorrect '%s'" + ", server incorrect", + endptr); + return true; + } startptr++; uint64_t seq __attribute__((unused)) (parse_value(&startptr, &endptr)); } // Remaining string was seqno. - if (*endptr == '\0') return false; + if (*endptr == '\0' || *endptr == '/') { + /* In migration MySQL 8.x start position can have additional info + i.e. local_seqno */ + if (*endptr == '/') + { + endptr++; + startptr= endptr; + uint64_t local_seqno __attribute__((unused)) + (parse_value(&startptr, &endptr)); + if (*endptr != '/') + { + push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN, + ER_WRONG_VALUE_FOR_VAR, + "wsrep_start_position incorrect '%s'" + ", local_seqno incorrect", + endptr); + return true; + } + + } + return false; + } + push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN, + ER_WRONG_VALUE_FOR_VAR, + "wsrep_start_position incorrect '%s'" + ", incorrect format", + endptr); return true; } @@ -295,7 +361,7 @@ bool wsrep_set_local_position(THD* thd, const char* const value, wsrep_uuid_t uuid; size_t const uuid_len= wsrep_uuid_scan(value, length, &uuid); startptr= (char *)value + uuid_len + 1; - wsrep_seqno_t const seqno= parse_value(&startptr, &endptr); + wsrep_seqno_t seqno= parse_value(&startptr, &endptr); if (*startptr == ',') { @@ -345,7 +411,7 @@ bool wsrep_start_position_check (sys_var *self, THD* thd, set_var* var) start_pos_buf, wsrep_start_position); // Verify the format. - if (wsrep_start_position_verify(start_pos_buf)) return true; + if (wsrep_start_position_verify(thd, start_pos_buf)) return true; // Give error if position is updated when wsrep is not enabled or // provider is not loaded. @@ -384,9 +450,9 @@ bool wsrep_start_position_update (sys_var *self, THD* thd, enum_var_type type) return false; } -bool wsrep_start_position_init (const char* val) +bool wsrep_start_position_init (THD* thd, const char* val) { - if (NULL == val || wsrep_start_position_verify (val)) + if (NULL == val || wsrep_start_position_verify(thd, val)) { WSREP_ERROR("Bad initial value for wsrep_start_position: %s", (val ? val : "")); diff --git a/sql/wsrep_var.h b/sql/wsrep_var.h index b4817ebd60b01..f1d326972b6d4 100644 --- a/sql/wsrep_var.h +++ b/sql/wsrep_var.h @@ -114,7 +114,7 @@ extern bool wsrep_forced_binlog_format_check CHECK_ARGS; #define wsrep_provider_init(X) #define wsrep_init_vars() (0) -#define wsrep_start_position_init(X) +#define wsrep_start_position_init(T,X) #endif /* WITH_WSREP */ #endif /* WSREP_VAR_H */