Commit d8df84aa authored by unknown's avatar unknown

2 bugfixes:

- Bug #985: "Between RESET SLAVE and START SLAVE, SHOW SLAVE STATUS is wrong."
Now RESET SLAVE puts correct info in mi->host etc. A new test rpl_reset_slave
for that.
- Bug #986: "CHANGE MASTER & START SLAVE do not reset error columns in SHOW
SLAVE STATUS". Now these reset the errors.


mysql-test/r/rpl_loaddata.result:
  result update.
mysql-test/t/rpl_loaddata.test:
  Test that RESET SLAVE, START SLAVE and CHANGE MASTER all reset 
  Last_slave_error and Last_slave_errno (columns of SHOW SLAVE STATUS).
  We do it in this test because that's one of tests which have 
  an intentional query error on the slave.
sql/slave.cc:
  As we need TWICE the code to copy command-line options (--master-host etc)
  to mi (we already had it in init_master_info, but we also need it in RESET
  SLAVE to fix bug#985), I make a function of this code.
  And a function to reset Last_slave_error and Last_slave_errno (we need
  it in CHANGE MASTER, RESET SLAVE, and at the start of the SQL thread).
sql/slave.h:
  declarations for new functions.
sql/sql_repl.cc:
  copy --master-host etc to mi in RESET SLAVE, so that SHOW SLAVE STATUS
  shows correct information.
parent 3b013646
......@@ -25,3 +25,29 @@ drop table t3;
create table t1(a int, b int, unique(b));
insert into t1 values(1,10);
load data infile '../../std_data/rpl_loaddata.dat' into table t1;
set global sql_slave_skip_counter=1;
start slave;
show slave status;
Master_Host Master_User Master_Port Connect_retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_do_db Replicate_ignore_db Last_errno Last_error Skip_counter Exec_master_log_pos Relay_log_space
127.0.0.1 root MASTER_PORT 1 master-bin.001 1311 slave-relay-bin.002 1352 master-bin.001 Yes Yes 0 0 1311 1352
set sql_log_bin=0;
delete from t1;
set sql_log_bin=1;
load data infile '../../std_data/rpl_loaddata.dat' into table t1;
stop slave;
change master to master_user='test';
change master to master_user='root';
show slave status;
Master_Host Master_User Master_Port Connect_retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_do_db Replicate_ignore_db Last_errno Last_error Skip_counter Exec_master_log_pos Relay_log_space
127.0.0.1 root MASTER_PORT 1 master-bin.001 1442 slave-relay-bin.001 4 master-bin.001 No No 0 0 1442 4
set global sql_slave_skip_counter=1;
start slave;
set sql_log_bin=0;
delete from t1;
set sql_log_bin=1;
load data infile '../../std_data/rpl_loaddata.dat' into table t1;
stop slave;
reset slave;
show slave status;
Master_Host Master_User Master_Port Connect_retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_do_db Replicate_ignore_db Last_errno Last_error Skip_counter Exec_master_log_pos Relay_log_space
127.0.0.1 root MASTER_PORT 1 4 slave-relay-bin.001 4 No No 0 0 0 4
slave stop;
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
reset master;
reset slave;
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
slave start;
show slave status;
Master_Host Master_User Master_Port Connect_retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_do_db Replicate_ignore_db Last_errno Last_error Skip_counter Exec_master_log_pos Relay_log_space
127.0.0.1 root MASTER_PORT 1 master-bin.001 79 slave-relay-bin.002 120 master-bin.001 Yes Yes 0 0 79 120
stop slave;
change master to master_user='test';
show slave status;
Master_Host Master_User Master_Port Connect_retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_do_db Replicate_ignore_db Last_errno Last_error Skip_counter Exec_master_log_pos Relay_log_space
127.0.0.1 test MASTER_PORT 1 master-bin.001 79 slave-relay-bin.001 4 master-bin.001 No No 0 0 79 4
reset slave;
show slave status;
Master_Host Master_User Master_Port Connect_retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_do_db Replicate_ignore_db Last_errno Last_error Skip_counter Exec_master_log_pos Relay_log_space
127.0.0.1 root MASTER_PORT 1 4 slave-relay-bin.001 4 No No 0 0 0 4
start slave;
show slave status;
Master_Host Master_User Master_Port Connect_retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_do_db Replicate_ignore_db Last_errno Last_error Skip_counter Exec_master_log_pos Relay_log_space
127.0.0.1 root MASTER_PORT 1 master-bin.001 79 slave-relay-bin.002 120 master-bin.001 Yes Yes 0 0 79 120
......@@ -6,6 +6,9 @@
#
# check if duplicate entries trigger an error (they should unless IGNORE or
# REPLACE was used on the master) (bug 571).
#
# check if START SLAVE, RESET SLAVE, CHANGE MASTER reset Last_slave_error and
# Last_slave_errno in SHOW SLAVE STATUS (1st and 3rd commands did not: bug 986).
source include/master-slave.inc;
......@@ -44,3 +47,53 @@ save_master_pos;
connection slave;
# The SQL slave thread should be stopped now.
wait_for_slave_to_stop;
# Skip the bad event and see if error is cleared in SHOW SLAVE STATUS by START
# SLAVE, even though we are not executing any event (as sql_slave_skip_counter
# takes us directly to the end of the relay log).
set global sql_slave_skip_counter=1;
start slave;
sync_with_master;
--replace_result $MASTER_MYPORT MASTER_PORT
show slave status;
# Trigger error again to test CHANGE MASTER
connection master;
set sql_log_bin=0;
delete from t1;
set sql_log_bin=1;
load data infile '../../std_data/rpl_loaddata.dat' into table t1;
save_master_pos;
connection slave;
# The SQL slave thread should be stopped now.
wait_for_slave_to_stop;
# CHANGE MASTER and see if error is cleared in SHOW SLAVE STATUS.
stop slave;
change master to master_user='test';
change master to master_user='root';
--replace_result $MASTER_MYPORT MASTER_PORT
show slave status;
# Trigger error again to test RESET SLAVE
set global sql_slave_skip_counter=1;
start slave;
sync_with_master;
connection master;
set sql_log_bin=0;
delete from t1;
set sql_log_bin=1;
load data infile '../../std_data/rpl_loaddata.dat' into table t1;
save_master_pos;
connection slave;
# The SQL slave thread should be stopped now.
wait_for_slave_to_stop;
# RESET SLAVE and see if error is cleared in SHOW SLAVE STATUS.
stop slave;
reset slave;
--replace_result $MASTER_MYPORT MASTER_PORT
show slave status;
# See SHOW SLAVE STATUS displays well after RESET SLAVE (it should display the
# --master-* options from mysqld, as this is what is going to be used next time
# slave threads will be started). In bug 985, it displayed old values (of before
# RESET SLAVE).
source include/master-slave.inc;
connection master;
save_master_pos;
connection slave;
sync_with_master;
--replace_result $MASTER_MYPORT MASTER_PORT
show slave status;
stop slave;
change master to master_user='test';
--replace_result $MASTER_MYPORT MASTER_PORT
show slave status;
reset slave;
--replace_result $MASTER_MYPORT MASTER_PORT
show slave status;
start slave;
sync_with_master;
--replace_result $MASTER_MYPORT MASTER_PORT
show slave status;
......@@ -1476,6 +1476,27 @@ static int count_relay_log_space(RELAY_LOG_INFO* rli)
DBUG_RETURN(0);
}
void init_master_info_with_options(MASTER_INFO* mi)
{
mi->master_log_name[0] = 0;
mi->master_log_pos = BIN_LOG_HEADER_SIZE; // skip magic number
if (master_host)
strmake(mi->host, master_host, sizeof(mi->host) - 1);
if (master_user)
strmake(mi->user, master_user, sizeof(mi->user) - 1);
if (master_password)
strmake(mi->password, master_password, HASH_PASSWORD_LENGTH);
mi->port = master_port;
mi->connect_retry = master_connect_retry;
}
void clear_last_slave_error(RELAY_LOG_INFO* rli)
{
//Clear the errors displayed by SHOW SLAVE STATUS
rli->last_slave_error[0]=0;
rli->last_slave_errno=0;
}
int init_master_info(MASTER_INFO* mi, const char* master_info_fname,
const char* slave_info_fname,
......@@ -1529,18 +1550,9 @@ file '%s')", fname);
goto err;
}
mi->master_log_name[0] = 0;
mi->master_log_pos = BIN_LOG_HEADER_SIZE; // skip magic number
mi->fd = fd;
if (master_host)
strmake(mi->host, master_host, sizeof(mi->host) - 1);
if (master_user)
strmake(mi->user, master_user, sizeof(mi->user) - 1);
if (master_password)
strmake(mi->password, master_password, HASH_PASSWORD_LENGTH);
mi->port = master_port;
mi->connect_retry = master_connect_retry;
init_master_info_with_options(mi);
}
else // file exists
{
......@@ -2611,6 +2623,12 @@ extern "C" pthread_handler_decl(handle_slave_sql,arg)
pthread_cond_broadcast(&rli->start_cond);
// This should always be set to 0 when the slave thread is started
rli->pending = 0;
/*
Reset errors for a clean start (otherwise, if the master is idle, the SQL
thread may execute no Query_log_event, so the error will remain even
though there's no problem anymore).
*/
clear_last_slave_error(rli);
//tell the I/O thread to take relay_log_space_limit into account from now on
pthread_mutex_lock(&rli->log_space_lock);
......
......@@ -389,6 +389,8 @@ void skip_load_data_infile(NET* net);
void slave_print_error(RELAY_LOG_INFO* rli, int err_code, const char* msg, ...);
void end_slave(); /* clean up */
void init_master_info_with_options(MASTER_INFO* mi);
void clear_last_slave_error(RELAY_LOG_INFO* rli);
int init_master_info(MASTER_INFO* mi, const char* master_info_fname,
const char* slave_info_fname,
bool abort_if_no_master_info_file);
......
......@@ -769,12 +769,15 @@ int reset_slave(THD *thd, MASTER_INFO* mi)
&errmsg)))
goto err;
//Clear master's log coordinates (only for good display of SHOW SLAVE STATUS)
mi->master_log_name[0]= 0;
mi->master_log_pos= BIN_LOG_HEADER_SIZE;
//Clear the errors displayed by SHOW SLAVE STATUS
mi->rli.last_slave_error[0]=0;
mi->rli.last_slave_errno=0;
/*
Clear master's log coordinates and reset host/user/etc to the values
specified in mysqld's options (only for good display of SHOW SLAVE STATUS;
next init_master_info() (in start_slave() for example) would have set them
the same way; but here this is for the case where the user does SHOW SLAVE
STATUS; before doing START SLAVE;
*/
init_master_info_with_options(mi);
clear_last_slave_error(&mi->rli);
//close master_info_file, relay_log_info_file, set mi->inited=rli->inited=0
end_master_info(mi);
//and delete these two files
......@@ -965,6 +968,8 @@ int change_master(THD* thd, MASTER_INFO* mi)
pthread_mutex_lock(&mi->rli.data_lock);
mi->rli.abort_pos_wait++; /* for MASTER_POS_WAIT() to abort */
/* Clear the error, for a clean start. */
clear_last_slave_error(&mi->rli);
/*
If we don't write new coordinates to disk now, then old will remain in
relay-log.info until START SLAVE is issued; but if mysqld is shutdown
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment