diff options
-rw-r--r-- | client/mysqltest.c | 15 | ||||
-rw-r--r-- | mysql-test/mysql-test-run.sh | 35 | ||||
-rw-r--r-- | mysql-test/r/rpl_failsafe.result | 10 | ||||
-rw-r--r-- | mysql-test/t/rpl000018.test | 1 | ||||
-rw-r--r-- | mysql-test/t/rpl_failsafe.test | 9 | ||||
-rw-r--r-- | sql/repl_failsafe.cc | 7 | ||||
-rw-r--r-- | sql/repl_failsafe.h | 5 | ||||
-rw-r--r-- | sql/slave.cc | 11 |
8 files changed, 84 insertions, 9 deletions
diff --git a/client/mysqltest.c b/client/mysqltest.c index c6169540469..1bf3ab75aed 100644 --- a/client/mysqltest.c +++ b/client/mysqltest.c @@ -181,7 +181,7 @@ Q_PING, Q_EVAL, Q_RPL_PROBE, Q_ENABLE_RPL_PARSE, Q_DISABLE_RPL_PARSE, Q_EVAL_RESULT, Q_ENABLE_QUERY_LOG, Q_DISABLE_QUERY_LOG, -Q_SERVER_START, Q_SERVER_STOP, +Q_SERVER_START, Q_SERVER_STOP,Q_REQUIRE_MANAGER, Q_UNKNOWN, /* Unknown command. */ Q_COMMENT, /* Comments, ignored. */ Q_COMMENT_WITH_COMMAND @@ -215,6 +215,7 @@ const char *command_names[] = { "disable_rpl_parse", "eval_result", "enable_query_log", "disable_query_log", "server_start", "server_stop", + "require_manager", 0 }; @@ -640,6 +641,13 @@ int open_file(const char* name) return 0; } +int do_require_manager(struct st_query* __attribute__((unused)) q) +{ + if (!manager) + abort_not_supported_test(); + return 0; +} + #ifndef EMBEDDED_LIBRARY int do_server_start(struct st_query* q) { @@ -1930,7 +1938,9 @@ int run_query(MYSQL* mysql, struct st_query* q, int flags) ds= &ds_res; if ((flags & QUERY_SEND) && mysql_send_query(mysql, query, query_len)) - die("At line %u: unable to send query '%s'", start_lineno, query); + die("At line %u: unable to send query '%s'(mysql_errno=%d,errno=%d)", + start_lineno, query, + mysql_errno(mysql), errno); if ((flags & QUERY_SEND) && !disable_query_log) { dynstr_append_mem(ds,query,query_len); @@ -2236,6 +2246,7 @@ int main(int argc, char** argv) case Q_DISABLE_QUERY_LOG: disable_query_log=1; break; case Q_SOURCE: do_source(q); break; case Q_SLEEP: do_sleep(q); break; + case Q_REQUIRE_MANAGER: do_require_manager(q); break; #ifndef EMBEDDED_LIBRARY case Q_SERVER_START: do_server_start(q); break; case Q_SERVER_STOP: do_server_stop(q); break; diff --git a/mysql-test/mysql-test-run.sh b/mysql-test/mysql-test-run.sh index 8f824d82a08..b601abce1fc 100644 --- a/mysql-test/mysql-test-run.sh +++ b/mysql-test/mysql-test-run.sh @@ -12,6 +12,7 @@ DB=test DBPASSWD= VERBOSE="" +NO_MANAGER="" TZ=GMT-3; export TZ # for UNIX_TIMESTAMP tests to work #++ @@ -162,6 +163,9 @@ while test $# -gt 0; do --ssl-ca=$BASEDIR/SSL/cacert.pem \ --ssl-cert=$BASEDIR/SSL/server-cert.pem \ --ssl-key=$BASEDIR/SSL/server-key.pem" ;; + --no-manager) + NO_MANAGER=1 + ;; --skip-innobase) EXTRA_MASTER_MYSQLD_OPT="$EXTRA_MASTER_MYSQLD_OPT --skip-innobase" EXTRA_SLAVE_MYSQLD_OPT="$EXTRA_SLAVE_MYSQLD_OPT --skip-innobase" ;; @@ -476,6 +480,7 @@ mysql_install_db () { for slave_num in 1 2 ; do + rm -rf var/slave$slave_num-data/ mkdir -p var/slave$slave_num-data/mysql mkdir -p var/slave$slave_num-data/test cp var/slave-data/mysql/* var/slave$slave_num-data/mysql @@ -533,6 +538,11 @@ abort_if_failed() start_manager() { + if [ -n "$NO_MANAGER" ] ; then + echo "Manager disabled, skipping manager start. Tests requiring manager will\ + be skipped" + return + fi MYSQL_MANAGER_PW=`$MYSQL_MANAGER_PWGEN -u $MYSQL_MANAGER_USER \ -o $MYSQL_MANAGER_PW_FILE` $MYSQL_MANAGER --log=$MYSQL_MANAGER_LOG --port=$MYSQL_MANAGER_PORT \ @@ -550,6 +560,9 @@ start_manager() stop_manager() { + if [ -n "$NO_MANAGER" ] ; then + return + fi $MYSQL_MANAGER_CLIENT $MANAGER_QUIET_OPT -u$MYSQL_MANAGER_USER \ -p$MYSQL_MANAGER_PW -P $MYSQL_MANAGER_PORT <<EOF shutdown @@ -560,6 +573,11 @@ manager_launch() { ident=$1 shift + if [ -n "$NO_MANAGER" ] ; then + $@ >$CUR_MYERR 2>&1 & + sleep 2 #hack + return + fi $MYSQL_MANAGER_CLIENT $MANAGER_QUIET_OPT --user=$MYSQL_MANAGER_USER \ --password=$MYSQL_MANAGER_PW --port=$MYSQL_MANAGER_PORT <<EOF def_exec $ident $@ @@ -575,6 +593,11 @@ manager_term() { ident=$1 shift + if [ -n "$NO_MANAGER" ] ; then + $MYSQLADMIN --no-defaults -uroot --socket=$MYSQL_TMP_DIR/$ident.sock -O \ + connect_timeout=5 shutdown >/dev/null 2>&1 + return + fi $MYSQL_MANAGER_CLIENT $MANAGER_QUIET_OPT --user=$MYSQL_MANAGER_USER \ --password=$MYSQL_MANAGER_PW --port=$MYSQL_MANAGER_PORT <<EOF stop_exec $ident $STOP_WAIT_TIMEOUT @@ -841,7 +864,10 @@ run_testcase () slave_init_script=$TESTDIR/$tname-slave.sh slave_master_info_file=$TESTDIR/$tname-slave-master-info.opt SKIP_SLAVE=`$EXPR \( $tname : rpl \) = 0` - many_slaves=`$EXPR \( $tname : rpl_failsafe \) != 0` + if [ -z "$NO_MANAGER" ] ; then + many_slaves=`$EXPR \( $tname : rpl_failsafe \) != 0` + fi + if [ -n "$SKIP_TEST" ] ; then SKIP_THIS_TEST=`$EXPR \( $tname : "$SKIP_TEST" \) != 0` if [ x$SKIP_THIS_TEST = x1 ] ; @@ -952,7 +978,12 @@ run_testcase () timestr="$USERT $SYST $REALT" pname=`$ECHO "$tname "|$CUT -c 1-24` RES="$pname $timestr" - + + if [ x$many_slaves = x1 ] ; then + stop_slave 1 + stop_slave 2 + fi + if [ $res = 0 ]; then total_inc pass_inc diff --git a/mysql-test/r/rpl_failsafe.result b/mysql-test/r/rpl_failsafe.result index 596d6ef7191..14b749fada9 100644 --- a/mysql-test/r/rpl_failsafe.result +++ b/mysql-test/r/rpl_failsafe.result @@ -9,21 +9,25 @@ rpl_recovery_rank 1 show status like 'Rpl_status'; Variable_name Value Rpl_status AUTH_MASTER +create table t1(n int); +drop table t1; show variables like 'rpl_recovery_rank'; Variable_name Value rpl_recovery_rank 2 show status like 'Rpl_status'; Variable_name Value -Rpl_status IDLE_SLAVE +Rpl_status ACTIVE_SLAVE +slave start; show variables like 'rpl_recovery_rank'; Variable_name Value rpl_recovery_rank 3 show status like 'Rpl_status'; Variable_name Value -Rpl_status IDLE_SLAVE +Rpl_status ACTIVE_SLAVE +slave start; show variables like 'rpl_recovery_rank'; Variable_name Value rpl_recovery_rank 4 show status like 'Rpl_status'; Variable_name Value -Rpl_status IDLE_SLAVE +Rpl_status ACTIVE_SLAVE diff --git a/mysql-test/t/rpl000018.test b/mysql-test/t/rpl000018.test index 621147b7c3e..30d601bb375 100644 --- a/mysql-test/t/rpl000018.test +++ b/mysql-test/t/rpl000018.test @@ -1,3 +1,4 @@ +require_manager; connect (master,localhost,root,,test,0,master.sock); connect (slave,localhost,root,,test,0,slave.sock); server_stop master; diff --git a/mysql-test/t/rpl_failsafe.test b/mysql-test/t/rpl_failsafe.test index f93dbf4b118..866efbce5bf 100644 --- a/mysql-test/t/rpl_failsafe.test +++ b/mysql-test/t/rpl_failsafe.test @@ -1,15 +1,24 @@ +require_manager; source include/master-slave.inc; connect (slave_sec,localhost,root,,test,0,slave.sock-1); connect (slave_ter,localhost,root,,test,0,slave.sock-2); connection master; show variables like 'rpl_recovery_rank'; show status like 'Rpl_status'; +create table t1(n int); +drop table t1; +save_master_pos; connection slave; +sync_with_master; show variables like 'rpl_recovery_rank'; show status like 'Rpl_status'; connection slave_sec; +slave start; +sync_with_master; show variables like 'rpl_recovery_rank'; show status like 'Rpl_status'; connection slave_ter; +slave start; +sync_with_master; show variables like 'rpl_recovery_rank'; show status like 'Rpl_status'; diff --git a/sql/repl_failsafe.cc b/sql/repl_failsafe.cc index bdd63bd9a10..40eb3b8bb7c 100644 --- a/sql/repl_failsafe.cc +++ b/sql/repl_failsafe.cc @@ -33,4 +33,11 @@ const char* rpl_status_type[] = {"AUTH_MASTER","ACTIVE_SLAVE","IDLE_SLAVE", TYPELIB rpl_status_typelib= {array_elements(rpl_status_type)-1,"", rpl_status_type}; +void change_rpl_status(RPL_STATUS from_status, RPL_STATUS to_status) +{ + pthread_mutex_lock(&LOCK_rpl_status); + if (rpl_status == from_status || rpl_status == RPL_ANY) + rpl_status = to_status; + pthread_mutex_unlock(&LOCK_rpl_status); +} diff --git a/sql/repl_failsafe.h b/sql/repl_failsafe.h index 95069404acb..42b386e6255 100644 --- a/sql/repl_failsafe.h +++ b/sql/repl_failsafe.h @@ -3,11 +3,14 @@ typedef enum {RPL_AUTH_MASTER=0,RPL_ACTIVE_SLAVE,RPL_IDLE_SLAVE, RPL_LOST_SOLDIER,RPL_TROOP_SOLDIER, - RPL_RECOVERY_CAPTAIN,RPL_NULL} RPL_STATUS; + RPL_RECOVERY_CAPTAIN,RPL_NULL /* inactive */, + RPL_ANY /* wild card used by change_rpl_status */ } RPL_STATUS; extern RPL_STATUS rpl_status; extern pthread_mutex_t LOCK_rpl_status; extern pthread_cond_t COND_rpl_status; extern TYPELIB rpl_role_typelib, rpl_status_typelib; extern const char* rpl_role_type[], *rpl_status_type[]; + +void change_rpl_status(RPL_STATUS from_status, RPL_STATUS to_status); #endif diff --git a/sql/slave.cc b/sql/slave.cc index d2e038bef88..7c065a89c9d 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -21,6 +21,7 @@ #include "mini_client.h" #include "slave.h" #include "sql_repl.h" +#include "repl_failsafe.h" #include <thr_alarm.h> #include <my_dir.h> @@ -1220,6 +1221,7 @@ position %s", thd->proc_info = "Waiting for slave mutex on exit"; pthread_mutex_lock(&LOCK_slave); slave_running = 0; + change_rpl_status(RPL_ACTIVE_SLAVE,RPL_IDLE_SLAVE); abort_slave = 0; save_temporary_tables = thd->temporary_tables; thd->temporary_tables = 0; // remove tempation from destructor to close them @@ -1257,6 +1259,7 @@ static int safe_connect(THD* thd, MYSQL* mysql, MASTER_INFO* mi) if(!slave_was_killed) { + change_rpl_status(RPL_IDLE_SLAVE,RPL_ACTIVE_SLAVE); mysql_log.write(thd, COM_CONNECT_OUT, "%s@%s:%d", mi->user, mi->host, mi->port); #ifdef SIGNAL_WITH_VIO_CLOSE @@ -1298,9 +1301,15 @@ static int safe_reconnect(THD* thd, MYSQL* mysql, MASTER_INFO* mi) mi->connect_retry); safe_sleep(thd, mi->connect_retry); } - if (err_count++ == master_retry_count) + /* by default we try forever. The reason is that failure will trigger + master election, so if the user did not set master_retry_count we + do not want to have electioin triggered on the first failure to + connect + */ + if (master_retry_count && err_count++ == master_retry_count) { slave_was_killed=1; + change_rpl_status(RPL_ACTIVE_SLAVE,RPL_LOST_SOLDIER); break; } } |