From ad3c42474c7c327408e3ebf6bcd87aca8ba77927 Mon Sep 17 00:00:00 2001 From: Mahmoud Khaled Date: Sat, 4 Apr 2026 17:45:28 +0200 Subject: [PATCH] MDEV-38202: Make init_rpl_role visible at runtime Problem: The --init-rpl-role option can be set in the .cnf file or command line to configure the server replication role at startup (MASTER or SLAVE), but there was no way to check this value at runtime. This made it hard to investigate issues because we could not know which role the server was started with. Solution: I added a new read-only system variable init_rpl_role that is set after startup and kept unchanged. Example usage: * SHOW GLOBAL VARIABLES LIKE 'init_rpl_role' * SELECT @@GLOBAL.init_rpl_role Reviewed-by: ParadoxV5 Reviewed-by: Georgi (Joro) Kodinov --- mysql-test/main/information_schema.result | 1 + mysql-test/main/mysqld--help.result | 4 +++- .../r/init_rpl_role_variable_basic.result | 17 +++++++++++++++++ .../r/sysvars_server_notembedded.result | 10 ++++++++++ .../t/init_rpl_role_variable_basic.opt | 1 + .../t/init_rpl_role_variable_basic.test | 18 ++++++++++++++++++ sql/mysqld.cc | 4 +--- sql/repl_failsafe.cc | 1 + sql/repl_failsafe.h | 1 + sql/sys_vars.cc | 11 +++++++++++ 10 files changed, 64 insertions(+), 4 deletions(-) create mode 100644 mysql-test/suite/sys_vars/r/init_rpl_role_variable_basic.result create mode 100644 mysql-test/suite/sys_vars/t/init_rpl_role_variable_basic.opt create mode 100644 mysql-test/suite/sys_vars/t/init_rpl_role_variable_basic.test diff --git a/mysql-test/main/information_schema.result b/mysql-test/main/information_schema.result index 547e5fea00af0..8c95371bc78aa 100644 --- a/mysql-test/main/information_schema.result +++ b/mysql-test/main/information_schema.result @@ -1939,6 +1939,7 @@ drop table if exists t1;drop table if exists t1; drop table if exists t1;drop table if exists t1; drop table if exists t1;drop table if exists t1; INIT_FILE +INIT_RPL_ROLE MASTER INIT_SLAVE set global init_connect=""; create table t0 select * from information_schema.global_status where VARIABLE_NAME='COM_SELECT'; diff --git a/mysql-test/main/mysqld--help.result b/mysql-test/main/mysqld--help.result index 1e228545846da..17458f8cf56ba 100644 --- a/mysql-test/main/mysqld--help.result +++ b/mysql-test/main/mysqld--help.result @@ -465,7 +465,9 @@ The following specify which files/extra groups are read (specified before remain (unless the user has SUPER privilege) --init-file=name Read SQL commands from this file at startup --init-rpl-role=name - Set the replication role. One of: MASTER, SLAVE + The replication role the server starts with. Can be set + to help recover special semi-sync replication situations. + Possible values are MASTER and SLAVE --init-slave=name Command(s) that are executed by a slave server each time the SQL thread starts --interactive-timeout=# diff --git a/mysql-test/suite/sys_vars/r/init_rpl_role_variable_basic.result b/mysql-test/suite/sys_vars/r/init_rpl_role_variable_basic.result new file mode 100644 index 0000000000000..33d007ee778cb --- /dev/null +++ b/mysql-test/suite/sys_vars/r/init_rpl_role_variable_basic.result @@ -0,0 +1,17 @@ +# +# MDEV-38202: add init_rpl_role in output of "show variables" +# +# It should show SLAVE as it is set in the .opt file. +SELECT @@GLOBAL.init_rpl_role; +@@GLOBAL.init_rpl_role +SLAVE +SHOW GLOBAL VARIABLES LIKE 'init_rpl_role'; +Variable_name Value +init_rpl_role SLAVE +# Verify that it's a global scope only. +SELECT @@SESSION.init_rpl_role; +ERROR HY000: Variable 'init_rpl_role' is a GLOBAL variable +# Verify it's read-only. +SET @@GLOBAL.init_rpl_role = 'MASTER'; +ERROR HY000: Variable 'init_rpl_role' is a read only variable +# End of 13.0 tests diff --git a/mysql-test/suite/sys_vars/r/sysvars_server_notembedded.result b/mysql-test/suite/sys_vars/r/sysvars_server_notembedded.result index 99f70165b7f14..268c06632b8b4 100644 --- a/mysql-test/suite/sys_vars/r/sysvars_server_notembedded.result +++ b/mysql-test/suite/sys_vars/r/sysvars_server_notembedded.result @@ -1582,6 +1582,16 @@ NUMERIC_BLOCK_SIZE NULL ENUM_VALUE_LIST NULL READ_ONLY YES COMMAND_LINE_ARGUMENT REQUIRED +VARIABLE_NAME INIT_RPL_ROLE +VARIABLE_SCOPE GLOBAL +VARIABLE_TYPE ENUM +VARIABLE_COMMENT The replication role the server starts with. Can be set to help recover special semi-sync replication situations. Possible values are MASTER and SLAVE +NUMERIC_MIN_VALUE NULL +NUMERIC_MAX_VALUE NULL +NUMERIC_BLOCK_SIZE NULL +ENUM_VALUE_LIST MASTER,SLAVE +READ_ONLY YES +COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME INIT_SLAVE VARIABLE_SCOPE GLOBAL VARIABLE_TYPE VARCHAR diff --git a/mysql-test/suite/sys_vars/t/init_rpl_role_variable_basic.opt b/mysql-test/suite/sys_vars/t/init_rpl_role_variable_basic.opt new file mode 100644 index 0000000000000..8ad18ef67cb01 --- /dev/null +++ b/mysql-test/suite/sys_vars/t/init_rpl_role_variable_basic.opt @@ -0,0 +1 @@ +--init-rpl-role=SLAVE diff --git a/mysql-test/suite/sys_vars/t/init_rpl_role_variable_basic.test b/mysql-test/suite/sys_vars/t/init_rpl_role_variable_basic.test new file mode 100644 index 0000000000000..2efe82e55f78a --- /dev/null +++ b/mysql-test/suite/sys_vars/t/init_rpl_role_variable_basic.test @@ -0,0 +1,18 @@ +--source include/not_embedded.inc +--echo # +--echo # MDEV-38202: add init_rpl_role in output of "show variables" +--echo # + +--echo # It should show SLAVE as it is set in the .opt file. +SELECT @@GLOBAL.init_rpl_role; +SHOW GLOBAL VARIABLES LIKE 'init_rpl_role'; + +--echo # Verify that it's a global scope only. +--error ER_INCORRECT_GLOBAL_LOCAL_VAR +SELECT @@SESSION.init_rpl_role; + +--echo # Verify it's read-only. +--error ER_INCORRECT_GLOBAL_LOCAL_VAR +SET @@GLOBAL.init_rpl_role = 'MASTER'; + +--echo # End of 13.0 tests diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 5ffff2cb12851..1aa5e0cfe7ddf 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -7086,9 +7086,6 @@ struct my_option my_long_options[]= "which is whether to validate the master's certificate in TLS replication", &master_ssl_verify_server_cert, nullptr, nullptr, GET_BOOL, NO_ARG, master_ssl_verify_server_cert, 0, 0, nullptr, 0, nullptr}, - {"init-rpl-role", 0, "Set the replication role", - &rpl_status, &rpl_status, &rpl_role_typelib, - GET_ENUM, REQUIRED_ARG, RPL_AUTH_MASTER, 0, 0, 0, 0, 0}, #endif /* HAVE_REPLICATION */ {"memlock", 0, "Lock mariadbd process in memory", &locked_in_memory, &locked_in_memory, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, @@ -9141,6 +9138,7 @@ static int get_options(int *argc_ptr, char ***argv_ptr) flush_time= 0; #ifdef HAVE_REPLICATION + rpl_status= init_rpl_role_val; if (init_slave_skip_errors(opt_slave_skip_errors)) return 1; if (init_slave_transaction_retry_errors(opt_slave_transaction_retry_errors)) diff --git a/sql/repl_failsafe.cc b/sql/repl_failsafe.cc index 164ae02df4d7f..f1dec4739ed26 100644 --- a/sql/repl_failsafe.cc +++ b/sql/repl_failsafe.cc @@ -52,6 +52,7 @@ struct Slave_info Atomic_counter binlog_dump_thread_count; ulong rpl_status=RPL_NULL; +ulong init_rpl_role_val= 0; mysql_mutex_t LOCK_rpl_status; const char *rpl_role_type[] = {"MASTER","SLAVE",NullS}; diff --git a/sql/repl_failsafe.h b/sql/repl_failsafe.h index 6f8bdfc521657..25aa2b537e805 100644 --- a/sql/repl_failsafe.h +++ b/sql/repl_failsafe.h @@ -29,6 +29,7 @@ typedef enum {RPL_AUTH_MASTER=0,RPL_IDLE_SLAVE,RPL_ACTIVE_SLAVE, RPL_ANY /* wild card used by change_rpl_status */ } RPL_STATUS; extern ulong rpl_status; +extern ulong init_rpl_role_val; extern mysql_mutex_t LOCK_rpl_status; extern mysql_cond_t COND_rpl_status; extern TYPELIB rpl_role_typelib; diff --git a/sql/sys_vars.cc b/sql/sys_vars.cc index d48ec3c03952a..d6becc62d8632 100644 --- a/sql/sys_vars.cc +++ b/sql/sys_vars.cc @@ -67,6 +67,7 @@ #include "semisync_master.h" #include "semisync_slave.h" #include +#include "repl_failsafe.h" #ifdef WITH_WSREP #include "wsrep_mysqld.h" #endif @@ -1505,6 +1506,16 @@ Sys_init_slave( DEFAULT(""), &PLock_sys_init_slave, NOT_IN_BINLOG, ON_CHECK(check_init_string)); +#ifdef HAVE_REPLICATION +static Sys_var_enum Sys_init_rpl_role( + "init_rpl_role", + "The replication role the server starts with. " + "Can be set to help recover " + "special semi-sync replication situations. " + "Possible values are MASTER and SLAVE", + READ_ONLY GLOBAL_VAR(init_rpl_role_val), CMD_LINE(REQUIRED_ARG), + rpl_role_type, DEFAULT(RPL_AUTH_MASTER)); +#endif static Sys_var_ulong Sys_interactive_timeout( "interactive_timeout", "The number of seconds the server waits for activity on an interactive "