Skip to content

Commit 87dbe8f

Browse files
committed
MDEV-7394 Make slave_skip_errors dynamic
Make slave_skip_errors dynamic so it can be changed while the slave is stopped. Attempts to change it while the slave is running are rejected with a clear error.
1 parent 92a4926 commit 87dbe8f

5 files changed

Lines changed: 111 additions & 6 deletions

File tree

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
# MDEV-7394 test dynamic slave_skip_error (writable when slaves stopped)
2+
include/master-slave.inc
3+
[connection master]
4+
connection slave;
5+
# should reduce error because slave is not stopped
6+
SET GLOBAL slave_skip_errors = "1062";
7+
ERROR HY000: This operation cannot be performed as you have a running slave ''; run STOP SLAVE '' first
8+
SELECT @@global.slave_skip_errors;
9+
@@global.slave_skip_errors
10+
NULL
11+
STOP SLAVE;
12+
# should work corerctly because slaves stopped
13+
SET GLOBAL slave_skip_errors = "1062"
14+
SELECT @@global.slave_skip_errors;
15+
@@global.slave_skip_errors
16+
NULL
17+
SET GLOBAL slave_skip_errors = "1050";
18+
SELECT @@global.slave_skip_errors;
19+
@@global.slave_skip_errors
20+
1050
21+
SET GLOBAL slave_skip_errors = "";
22+
SELECT @@global.slave_skip_errors;
23+
@@global.slave_skip_errors
24+
25+
START SLAVE;
26+
# should reduce error because slave is not stopped
27+
SET GLOBAL slave_skip_errors = "1040";
28+
ERROR HY000: This operation cannot be performed as you have a running slave ''; run STOP SLAVE '' first
29+
include/rpl_end.inc
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
--echo # MDEV-7394 test dynamic slave_skip_error (writable when slaves stopped)
2+
3+
--source include/master-slave.inc
4+
5+
--connection slave
6+
7+
--echo # should reduce error because slave is not stopped
8+
--error ER_SLAVE_MUST_STOP
9+
SET GLOBAL slave_skip_errors = "1062";
10+
SELECT @@global.slave_skip_errors;
11+
12+
STOP SLAVE;
13+
echo # should work corerctly because slaves stopped
14+
SET GLOBAL slave_skip_errors = "1062";
15+
SELECT @@global.slave_skip_errors;
16+
17+
SET GLOBAL slave_skip_errors = "1050";
18+
SELECT @@global.slave_skip_errors;
19+
20+
SET GLOBAL slave_skip_errors = "";
21+
SELECT @@global.slave_skip_errors;
22+
23+
START SLAVE;
24+
--echo # should reduce error because slave is not stopped
25+
--error ER_SLAVE_MUST_STOP
26+
SET GLOBAL slave_skip_errors = "1040";
27+
28+
--source include/rpl_end.inc

sql/slave.cc

Lines changed: 48 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -711,8 +711,8 @@ static void make_slave_skip_errors_printable(void)
711711
DBUG_ASSERT(sizeof(slave_skip_error_names) > MIN_ROOM);
712712
DBUG_ASSERT(MAX_SLAVE_ERROR <= 999999); // 6 digits
713713

714-
/* Make @@slave_skip_errors show the nice human-readable value. */
715-
opt_slave_skip_errors= slave_skip_error_names;
714+
/* we should not touch opt_slave_skip_errors here. we just build the printable string only. */
715+
(void) opt_slave_skip_errors;
716716

717717
if (!use_slave_mask || bitmap_is_clear_all(&slave_error_mask))
718718
{
@@ -774,8 +774,15 @@ bool init_slave_skip_errors(const char* arg)
774774
if (!arg || !*arg) // No errors defined
775775
goto end;
776776

777-
if (my_bitmap_init(&slave_error_mask,0,MAX_SLAVE_ERROR))
778-
DBUG_RETURN(1);
777+
if (!slave_error_mask.bitmap)
778+
{
779+
if (my_bitmap_init(&slave_error_mask, 0, MAX_SLAVE_ERROR))
780+
DBUG_RETURN(1);
781+
}
782+
else
783+
{
784+
bitmap_clear_all(&slave_error_mask);
785+
}
779786

780787
use_slave_mask= 1;
781788
for (;my_isspace(system_charset_info,*arg);++arg)
@@ -801,6 +808,43 @@ bool init_slave_skip_errors(const char* arg)
801808
DBUG_RETURN(0);
802809
}
803810

811+
812+
bool check_slave_skip_errors(sys_var *self, THD *thd, set_var *var)
813+
{
814+
return give_error_if_slave_running(0);
815+
}
816+
817+
818+
bool update_slave_skip_errors(sys_var *self, THD *thd, enum_var_type type)
819+
{
820+
bool res= false;
821+
mysql_mutex_unlock(&LOCK_global_system_variables);
822+
mysql_mutex_lock(&LOCK_active_mi);
823+
824+
if (active_mi->slave_running)
825+
{
826+
my_error(ER_SLAVE_MUST_STOP, MYF(0));
827+
res= true;
828+
}
829+
else
830+
{
831+
if (use_slave_mask)
832+
my_bitmap_free(&slave_error_mask);
833+
834+
use_slave_mask= 0;
835+
836+
if (init_slave_skip_errors(opt_slave_skip_errors))
837+
{
838+
my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), "slave_skip_errors", opt_slave_skip_errors);
839+
res= true;
840+
}
841+
}
842+
843+
mysql_mutex_unlock(&LOCK_active_mi);
844+
mysql_mutex_lock(&LOCK_global_system_variables);
845+
return res;
846+
}
847+
804848
/**
805849
Make printable version if slave_transaction_retry_errors
806850
This is never empty as at least ER_LOCK_DEADLOCK and ER_LOCK_WAIT_TIMEOUT

sql/slave.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,8 @@ extern const char *relay_log_basename;
190190
int init_slave();
191191
int init_recovery(Master_info* mi, const char** errmsg);
192192
bool init_slave_skip_errors(const char* arg);
193+
bool check_slave_skip_errors(sys_var *self, THD *thd, set_var *var);
194+
bool update_slave_skip_errors(sys_var *self, THD *thd, enum_var_type type);
193195
bool init_slave_transaction_retry_errors(const char* arg);
194196
int register_slave_on_master(MYSQL* mysql);
195197
int terminate_slave_threads(Master_info* mi, int thread_mask,

sql/sys_vars.cc

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6243,8 +6243,10 @@ static Sys_var_charptr Sys_slave_skip_errors(
62436243
"slave_skip_errors", "Tells the slave thread to continue "
62446244
"replication when a query event returns an error from the "
62456245
"provided list",
6246-
READ_ONLY GLOBAL_VAR(opt_slave_skip_errors), CMD_LINE(REQUIRED_ARG),
6247-
DEFAULT(0));
6246+
GLOBAL_VAR(opt_slave_skip_errors), CMD_LINE(REQUIRED_ARG),
6247+
DEFAULT(0), NO_MUTEX_GUARD, NOT_IN_BINLOG,
6248+
ON_CHECK(check_slave_skip_errors),
6249+
ON_UPDATE(update_slave_skip_errors));
62486250

62496251
static Sys_var_on_access_global<Sys_var_ulonglong,
62506252
PRIV_SET_SYSTEM_GLOBAL_VAR_READ_BINLOG_SPEED_LIMIT>

0 commit comments

Comments
 (0)