From 11f1ab1069b63b6b6cc445b538e1daffa848d6d7 Mon Sep 17 00:00:00 2001 From: Luis Soares Date: Wed, 3 Jun 2009 15:14:18 +0100 Subject: [PATCH] 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(). --- .../extra/rpl_tests/rpl_reset_slave.test | 54 +++++++++++++++++++ .../suite/rpl/r/rpl_row_reset_slave.result | 23 ++++++++ .../suite/rpl/r/rpl_stm_reset_slave.result | 23 ++++++++ sql/slave.cc | 3 ++ sql/sql_repl.cc | 1 + 5 files changed, 104 insertions(+) diff --git a/mysql-test/extra/rpl_tests/rpl_reset_slave.test b/mysql-test/extra/rpl_tests/rpl_reset_slave.test index 2cc041a35e1..49a142f10c2 100644 --- a/mysql-test/extra/rpl_tests/rpl_reset_slave.test +++ b/mysql-test/extra/rpl_tests/rpl_reset_slave.test @@ -41,3 +41,57 @@ reset slave; start slave; sync_with_master; 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 *** diff --git a/mysql-test/suite/rpl/r/rpl_row_reset_slave.result b/mysql-test/suite/rpl/r/rpl_row_reset_slave.result index 6126ec4bacc..fa40d8760a8 100644 --- a/mysql-test/suite/rpl/r/rpl_row_reset_slave.result +++ b/mysql-test/suite/rpl/r/rpl_row_reset_slave.result @@ -174,3 +174,26 @@ start slave; show status like 'slave_open_temp_tables'; Variable_name Value 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: *** diff --git a/mysql-test/suite/rpl/r/rpl_stm_reset_slave.result b/mysql-test/suite/rpl/r/rpl_stm_reset_slave.result index bb89d150af7..78d9d7c41eb 100644 --- a/mysql-test/suite/rpl/r/rpl_stm_reset_slave.result +++ b/mysql-test/suite/rpl/r/rpl_stm_reset_slave.result @@ -174,3 +174,26 @@ start slave; show status like 'slave_open_temp_tables'; Variable_name Value 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: *** diff --git a/sql/slave.cc b/sql/slave.cc index c379a67201a..679de890801 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -2397,6 +2397,7 @@ pthread_handler_t handle_slave_io(void *arg) pthread_detach_this_thread(); thd->thread_stack= (char*) &thd; // remember where our stack is + mi->clear_error(); if (init_slave_thread(thd, SLAVE_THD_IO)) { pthread_cond_broadcast(&mi->start_cond); @@ -2511,6 +2512,7 @@ requesting master dump") || goto connected; }); + DBUG_ASSERT(mi->last_error().number == 0); while (!io_slave_killed(thd,mi)) { ulong event_len; @@ -3710,6 +3712,7 @@ static int connect_to_master(THD* thd, MYSQL* mysql, Master_info* mi, if (!slave_was_killed) { + mi->clear_error(); // clear possible left over reconnect error if (reconnect) { if (!suppress_warnings && global_system_variables.log_warnings) diff --git a/sql/sql_repl.cc b/sql/sql_repl.cc index 06c6c022780..b34b3aef51f 100644 --- a/sql/sql_repl.cc +++ b/sql/sql_repl.cc @@ -1043,6 +1043,7 @@ int reset_slave(THD *thd, Master_info* mi) Reset errors (the idea is that we forget about the old master). */ + mi->clear_error(); mi->rli.clear_error(); mi->rli.clear_until_condition();