Commit 11f1ab10 authored by Luis Soares's avatar Luis Soares

BUG#44270: RESET SLAVE does not reset Last_IO_Error or Last_IO_Errno

The server was not cleaning the last IO error and error number when
resetting slave.

This patch addresses this issue by backporting into 5.1 part of the
patch in BUG 34654. A fix for this issue had already been pushed into
6.0 as part of the aforementioned bug, however the patch also included
some refactoring. The fix for 5.1 does not take into account the
refactoring part.

mysql-test/extra/rpl_tests/rpl_reset_slave.test:
  Backported the test case and improved with deploying include/start_slave.inc
  in relevant spots.
sql/slave.cc:
  Backported part of patch from 6.0 that includes cleaning 
  mi->clear_error() at:
    1. beginning of handle_slave_io
    2. on successful connection
  
  Also, backported the assertion added in the original patch.
sql/sql_repl.cc:
  Backported the call to mi->clear_error() on reset_slave().
parent 76e12894
...@@ -41,3 +41,57 @@ reset slave; ...@@ -41,3 +41,57 @@ reset slave;
start slave; start slave;
sync_with_master; sync_with_master;
show status like 'slave_open_temp_tables'; show status like 'slave_open_temp_tables';
#
#Bug#34654 RESET SLAVE does not clear LAST_IO_Err*
#
# clearing the status
stop slave;
reset slave;
let $last_io_errno= query_get_value(SHOW SLAVE STATUS, Last_IO_Errno, 1);
echo *** errno must be zero: $last_io_errno ***;
#
# verifying start slave resets Last_IO_Error and Last_IO_Errno.
#
change master to master_user='impossible_user_name';
start slave;
source include/wait_for_slave_io_to_stop.inc;
let $last_io_errno= query_get_value(SHOW SLAVE STATUS, Last_IO_Errno, 1);
--disable_query_log
eval SELECT $last_io_errno > 0 as ONE;
--enable_query_log
source include/stop_slave.inc;
change master to master_user='root';
source include/start_slave.inc;
let $last_io_errno= query_get_value(SHOW SLAVE STATUS, Last_IO_Errno, 1);
let $last_io_error= query_get_value(SHOW SLAVE STATUS, Last_IO_Error, 1);
--echo *** last errno must be zero: $last_io_errno ***
--echo *** last error must be blank: $last_io_error ***
#
# verifying reset slave resets Last_{IO,SQL}_Err{or,no}
#
source include/stop_slave.inc;
change master to master_user='impossible_user_name';
start slave;
source include/wait_for_slave_io_to_stop.inc;
let $last_io_errno= query_get_value(SHOW SLAVE STATUS, Last_IO_Errno, 1);
--disable_query_log
eval SELECT $last_io_errno > 0 as ONE;
--enable_query_log
source include/stop_slave.inc;
reset slave;
let $last_io_errno= query_get_value(SHOW SLAVE STATUS, Last_IO_Errno, 1);
let $last_io_error= query_get_value(SHOW SLAVE STATUS, Last_IO_Error, 1);
let $last_sql_errno= query_get_value(SHOW SLAVE STATUS, Last_SQL_Errno, 1);
let $last_sql_error= query_get_value(SHOW SLAVE STATUS, Last_SQL_Error, 1);
--echo *** io last errno must be zero: $last_io_errno ***
--echo *** io last error must be blank: $last_io_error ***
--echo *** sql last errno must be zero: $last_sql_errno ***
--echo *** sql last error must be blank: $last_sql_error ***
...@@ -174,3 +174,26 @@ start slave; ...@@ -174,3 +174,26 @@ start slave;
show status like 'slave_open_temp_tables'; show status like 'slave_open_temp_tables';
Variable_name Value Variable_name Value
Slave_open_temp_tables 0 Slave_open_temp_tables 0
stop slave;
reset slave;
*** errno must be zero: 0 ***
change master to master_user='impossible_user_name';
start slave;
ONE
1
include/stop_slave.inc
change master to master_user='root';
include/start_slave.inc
*** last errno must be zero: 0 ***
*** last error must be blank: ***
include/stop_slave.inc
change master to master_user='impossible_user_name';
start slave;
ONE
1
include/stop_slave.inc
reset slave;
*** io last errno must be zero: 0 ***
*** io last error must be blank: ***
*** sql last errno must be zero: 0 ***
*** sql last error must be blank: ***
...@@ -174,3 +174,26 @@ start slave; ...@@ -174,3 +174,26 @@ start slave;
show status like 'slave_open_temp_tables'; show status like 'slave_open_temp_tables';
Variable_name Value Variable_name Value
Slave_open_temp_tables 1 Slave_open_temp_tables 1
stop slave;
reset slave;
*** errno must be zero: 0 ***
change master to master_user='impossible_user_name';
start slave;
ONE
1
include/stop_slave.inc
change master to master_user='root';
include/start_slave.inc
*** last errno must be zero: 0 ***
*** last error must be blank: ***
include/stop_slave.inc
change master to master_user='impossible_user_name';
start slave;
ONE
1
include/stop_slave.inc
reset slave;
*** io last errno must be zero: 0 ***
*** io last error must be blank: ***
*** sql last errno must be zero: 0 ***
*** sql last error must be blank: ***
...@@ -2397,6 +2397,7 @@ pthread_handler_t handle_slave_io(void *arg) ...@@ -2397,6 +2397,7 @@ pthread_handler_t handle_slave_io(void *arg)
pthread_detach_this_thread(); pthread_detach_this_thread();
thd->thread_stack= (char*) &thd; // remember where our stack is thd->thread_stack= (char*) &thd; // remember where our stack is
mi->clear_error();
if (init_slave_thread(thd, SLAVE_THD_IO)) if (init_slave_thread(thd, SLAVE_THD_IO))
{ {
pthread_cond_broadcast(&mi->start_cond); pthread_cond_broadcast(&mi->start_cond);
...@@ -2511,6 +2512,7 @@ requesting master dump") || ...@@ -2511,6 +2512,7 @@ requesting master dump") ||
goto connected; goto connected;
}); });
DBUG_ASSERT(mi->last_error().number == 0);
while (!io_slave_killed(thd,mi)) while (!io_slave_killed(thd,mi))
{ {
ulong event_len; ulong event_len;
...@@ -3710,6 +3712,7 @@ static int connect_to_master(THD* thd, MYSQL* mysql, Master_info* mi, ...@@ -3710,6 +3712,7 @@ static int connect_to_master(THD* thd, MYSQL* mysql, Master_info* mi,
if (!slave_was_killed) if (!slave_was_killed)
{ {
mi->clear_error(); // clear possible left over reconnect error
if (reconnect) if (reconnect)
{ {
if (!suppress_warnings && global_system_variables.log_warnings) if (!suppress_warnings && global_system_variables.log_warnings)
......
...@@ -1043,6 +1043,7 @@ int reset_slave(THD *thd, Master_info* mi) ...@@ -1043,6 +1043,7 @@ int reset_slave(THD *thd, Master_info* mi)
Reset errors (the idea is that we forget about the Reset errors (the idea is that we forget about the
old master). old master).
*/ */
mi->clear_error();
mi->rli.clear_error(); mi->rli.clear_error();
mi->rli.clear_until_condition(); mi->rli.clear_until_condition();
......
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