From: Date: July 3 2009 2:41pm Subject: bzr commit into mysql-5.1-bugteam branch (Dao-Gang.Qu:2941) Bug#45214 List-Archive: http://lists.mysql.com/commits/77902 X-Bug: 45214 Message-Id: <200907031242.n63Cg5vI021285@daogangq-laptop.localdomain> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="===============1368599721==" --===============1368599721== MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Content-Disposition: inline #At file:///home/daogangq/mysql/bzrwork/bug45214/5.1-bt/ based on revid:davi.arnaut@stripped 2941 Dao-Gang.Qu@stripped 2009-07-03 Bug #45214 get_master_version_and_clock does not report error when queries fail The "get_master_version_and_clock(...)" function in sql/slave.cc ignores error and passes directly when queries fail, or queries succeed but the result retrieved is empty. The "get_master_version_and_clock(...)" function should try to reconnect master if queries fail because of transient network problems, and fail otherwise. The I/O thread should print a warning if the some system variables do not exist on master (very old master) @ mysql-test/extra/rpl_tests/rpl_get_master_version_and_clock.test Added test file for bug #45214 @ mysql-test/suite/rpl/r/rpl_get_master_version_and_clock.result Added test result for bug #45214 @ mysql-test/suite/rpl/t/rpl_get_master_version_and_clock.test Added test file for bug #45214 @ sql/slave.cc The 'is_network_error()' function is added for checking if the error is caused by network. Added a new return value (2) to 'get_master_version_and_clock()' function result set to indicate transient network errors when queries fail, and the caller should try to reconnect in this case. added: mysql-test/extra/rpl_tests/rpl_get_master_version_and_clock.test mysql-test/suite/rpl/r/rpl_get_master_version_and_clock.result mysql-test/suite/rpl/t/rpl_get_master_version_and_clock.test modified: sql/slave.cc === added file 'mysql-test/extra/rpl_tests/rpl_get_master_version_and_clock.test' --- a/mysql-test/extra/rpl_tests/rpl_get_master_version_and_clock.test 1970-01-01 00:00:00 +0000 +++ b/mysql-test/extra/rpl_tests/rpl_get_master_version_and_clock.test 2009-07-03 12:41:48 +0000 @@ -0,0 +1,63 @@ +# +# BUG#45214 +# The common part of the "rpl_get_master_version_and_clock" test. +# Restart slave under network disconnection between slave and master +# following the steps: +# 1 - Got DBUG_SYNC_POINT lock +# 2 - Set DBUG_SYNC_POINT before call mysql_real_query(...) function in get_master_version_and_clock(...) function and hang here +# 3 - shutdown master server for simulating network disconnection +# 4 - Release DBUG_SYNC_POINT lock +# 5 - Check if the slave I/O thread tries to reconnect to master. +# +# Note: Please make sure initialize the $debug_lock when call the test script. +# +connection slave; +if (`SELECT '$debug_lock' = ''`) +{ + --die Cannot continue. Please set value for $debug_lock. +} + +# Restart slave +--disable_warnings +stop slave; +source include/wait_for_slave_to_stop.inc; +start slave; +source include/wait_for_slave_to_start.inc; +connection master; +# Write file to make mysql-test-run.pl expect the "crash", but don't start +# it until it's told to +--write_file $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +wait +EOF + +# Send shutdown to the connected server and give +# it 10 seconds to die before zapping it +shutdown_server 10; + +connection slave; +eval SELECT RELEASE_LOCK($debug_lock); + +# Write file to make mysql-test-run.pl start up the server again +--append_file $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +restart +EOF + +connection master; +# Turn on reconnect +--enable_reconnect + +# Call script that will poll the server waiting for it to be back online again +--source include/wait_until_connected_again.inc + +# Turn off reconnect again +--disable_reconnect + +connection slave; +source include/wait_for_slave_to_start.inc; + +# Show slave last IO errno +let $last_io_errno= query_get_value("show slave status", Last_IO_Errno, 1); +echo Slave_IO_Errno= $last_io_errno; + + +# End of tests === added file 'mysql-test/suite/rpl/r/rpl_get_master_version_and_clock.result' --- a/mysql-test/suite/rpl/r/rpl_get_master_version_and_clock.result 1970-01-01 00:00:00 +0000 +++ b/mysql-test/suite/rpl/r/rpl_get_master_version_and_clock.result 2009-07-03 12:41:48 +0000 @@ -0,0 +1,40 @@ +stop slave; +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; +start slave; +SELECT IS_FREE_LOCK("debug_lock.before_get_UNIX_TIMESTAMP"); +IS_FREE_LOCK("debug_lock.before_get_UNIX_TIMESTAMP") +1 +SELECT GET_LOCK("debug_lock.before_get_UNIX_TIMESTAMP", 1000); +GET_LOCK("debug_lock.before_get_UNIX_TIMESTAMP", 1000) +1 +set global debug= 'd,debug_lock.before_get_UNIX_TIMESTAMP'; +stop slave; +start slave; +SELECT RELEASE_LOCK("debug_lock.before_get_UNIX_TIMESTAMP"); +RELEASE_LOCK("debug_lock.before_get_UNIX_TIMESTAMP") +1 +Slave_IO_Errno= 2013 +SELECT IS_FREE_LOCK("debug_lock.before_get_SERVER_ID"); +IS_FREE_LOCK("debug_lock.before_get_SERVER_ID") +1 +SELECT GET_LOCK("debug_lock.before_get_SERVER_ID", 1000); +GET_LOCK("debug_lock.before_get_SERVER_ID", 1000) +1 +set global debug= 'd,debug_lock.before_get_SERVER_ID'; +stop slave; +start slave; +SELECT RELEASE_LOCK("debug_lock.before_get_SERVER_ID"); +RELEASE_LOCK("debug_lock.before_get_SERVER_ID") +1 +Slave_IO_Errno= 2013 +set global debug= ''; +reset master; +include/stop_slave.inc +change master to master_port=SLAVE_PORT; +start slave; +*** must be having the replicate-same-server-id IO thread error *** +Slave_IO_Errno= 1593 +Slave_IO_Error= Fatal error: The slave I/O thread stops because master and slave have equal MySQL server ids; these ids must be different for replication to work (or the --replicate-same-server-id option must be used on slave but this does not always make sense; please check the manual before using it). === added file 'mysql-test/suite/rpl/t/rpl_get_master_version_and_clock.test' --- a/mysql-test/suite/rpl/t/rpl_get_master_version_and_clock.test 1970-01-01 00:00:00 +0000 +++ b/mysql-test/suite/rpl/t/rpl_get_master_version_and_clock.test 2009-07-03 12:41:48 +0000 @@ -0,0 +1,60 @@ +# +# BUG#45214 +# This test verifies if the slave I/O tread tries to reconnect to +# master when it tries to get the values of the UNIX_TIMESTAMP, SERVER_ID, +# COLLATION_SERVER and TIME_ZONE from master under network disconnection. +# The COLLATION_SERVER and TIME_ZONE are got only on master server version 4. +# So they can't be verified by test case here. +# Finish the following tests by calling its common test script: +# extra/rpl_tests/rpl_get_master_version_and_clock.test. +# And meanwhile this test checks that the slave I/O thread refuses to start if slave +# and master have the same server id (because this is a useless setup, +# and otherwise SHOW SLAVE STATUS shows progress but all queries are +# ignored, which has caught our customers), unless +# --replicate-same-server-id. +# + +source include/master-slave.inc; + +#Test case 1: Try to get the value of the UNIX_TIMESTAMP from master under network disconnection +connection slave; +let $debug_saved= `select @@global.debug`; + +let $debug_lock= "debug_lock.before_get_UNIX_TIMESTAMP"; +eval SELECT IS_FREE_LOCK($debug_lock); +eval SELECT GET_LOCK($debug_lock, 1000); + +set global debug= 'd,debug_lock.before_get_UNIX_TIMESTAMP'; +source extra/rpl_tests/rpl_get_master_version_and_clock.test; + +#Test case 2: Try to get the value of the SERVER_ID from master under network disconnection +connection slave; +let $debug_lock= "debug_lock.before_get_SERVER_ID"; +eval SELECT IS_FREE_LOCK($debug_lock); +eval SELECT GET_LOCK($debug_lock, 1000); + +set global debug= 'd,debug_lock.before_get_SERVER_ID'; +source extra/rpl_tests/rpl_get_master_version_and_clock.test; + +eval set global debug= '$debug_saved'; + +#Test case 3: This test checks that the slave I/O thread refuses to start +#if slave and master have the same server id. +connection slave; +reset master; +# replicate ourselves +source include/stop_slave.inc; +--replace_result $SLAVE_MYPORT SLAVE_PORT +eval change master to master_port=$SLAVE_MYPORT; +start slave; + +let $slave_param= Last_IO_Errno; +let $slave_param_value= 1593; +#source include/wait_for_slave_param.inc; +--echo *** must be having the replicate-same-server-id IO thread error *** +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 Slave_IO_Errno= $last_io_errno; +echo Slave_IO_Error= $last_io_error; + +# End of tests === modified file 'sql/slave.cc' --- a/sql/slave.cc 2009-06-09 16:44:26 +0000 +++ b/sql/slave.cc 2009-07-03 12:41:48 +0000 @@ -38,6 +38,7 @@ #include #include #include +#include #include #ifdef HAVE_REPLICATION @@ -842,6 +843,29 @@ int init_intvar_from_file(int* var, IO_C DBUG_RETURN(1); } + +/* + Check if the error is caused by network. + @param[in] errorno Number of the error. + RETURNS: + TRUE network error + FALSE not network error +*/ + +bool is_network_error(uint errorno) +{ + if (errorno == CR_CONNECTION_ERROR || + errorno == CR_CONN_HOST_ERROR || + errorno == CR_SERVER_GONE_ERROR || + errorno == CR_SERVER_LOST || + errorno == ER_CON_COUNT_ERROR || + errorno == ER_SERVER_SHUTDOWN) + return TRUE; + + return FALSE; +} + + /* Note that we rely on the master's version (3.23, 4.0.14 etc) instead of relying on the binlog's version. This is not perfect: imagine an upgrade @@ -854,6 +878,7 @@ int init_intvar_from_file(int* var, IO_C RETURNS 0 ok 1 error + 2 transient network problem, the caller should try to reconnect */ static int get_master_version_and_clock(MYSQL* mysql, Master_info* mi) @@ -864,6 +889,7 @@ static int get_master_version_and_clock( MYSQL_RES *master_res= 0; MYSQL_ROW master_row; DBUG_ENTER("get_master_version_and_clock"); + int query_re= 0; /* Free old description_event_for_queue (that is needed if we are in @@ -939,6 +965,8 @@ static int get_master_version_and_clock( unavailable (very old master not supporting UNIX_TIMESTAMP()?). */ + DBUG_SYNC_POINT("debug_lock.before_get_UNIX_TIMESTAMP", 10); + master_res= NULL; if (!mysql_real_query(mysql, STRING_WITH_LEN("SELECT UNIX_TIMESTAMP()")) && (master_res= mysql_store_result(mysql)) && (master_row= mysql_fetch_row(master_res))) @@ -946,7 +974,13 @@ static int get_master_version_and_clock( mi->clock_diff_with_master= (long) (time((time_t*) 0) - strtoul(master_row[0], 0, 10)); } - else if (!check_io_slave_killed(mi->io_thd, mi, NULL)) + else if (is_network_error(mysql_errno(mysql))) + { + mi->report(WARNING_LEVEL, mysql_errno(mysql), + "Get master clock failed with error: %s", mysql_error(mysql)); + goto network_err; + } + else { mi->clock_diff_with_master= 0; /* The "most sensible" value */ sql_print_warning("\"SELECT UNIX_TIMESTAMP()\" failed on master, " @@ -955,7 +989,10 @@ static int get_master_version_and_clock( mysql_error(mysql), mysql_errno(mysql)); } if (master_res) + { mysql_free_result(master_res); + master_res= NULL; + } /* Check that the master's server id and ours are different. Because if they @@ -967,12 +1004,15 @@ static int get_master_version_and_clock( Note: we could have put a @@SERVER_ID in the previous SELECT UNIX_TIMESTAMP() instead, but this would not have worked on 3.23 masters. */ + DBUG_SYNC_POINT("debug_lock.before_get_SERVER_ID", 10); + master_res= NULL; + master_row= NULL; if (!mysql_real_query(mysql, STRING_WITH_LEN("SHOW VARIABLES LIKE 'SERVER_ID'")) && - (master_res= mysql_store_result(mysql))) + (master_res= mysql_store_result(mysql)) && + (master_row= mysql_fetch_row(master_res))) { - if ((master_row= mysql_fetch_row(master_res)) && - (::server_id == strtoul(master_row[1], 0, 10)) && + if ((::server_id == strtoul(master_row[1], 0, 10)) && !mi->rli.replicate_same_server_id) { errmsg= "The slave I/O thread stops because master and slave have equal \ @@ -981,10 +1021,34 @@ the --replicate-same-server-id option mu not always make sense; please check the manual before using it)."; err_code= ER_SLAVE_FATAL_ERROR; sprintf(err_buff, ER(err_code), errmsg); + goto err; } + } + else if (mysql_errno(mysql)) + { + if (is_network_error(mysql_errno(mysql))) + { + mi->report(WARNING_LEVEL, mysql_errno(mysql), + "Get master SERVER_ID failed with error: %s", mysql_error(mysql)); + goto network_err; + } + /* Fatal error */ + errmsg= "The slave I/O thread stops because a fatal error is encountered \ +when it try to get the value of SERVER_ID variable from master."; + err_code= ER_SLAVE_FATAL_ERROR; + sprintf(err_buff, ER(err_code), errmsg); + goto err; + } + else if (!master_row && master_res) + { + mi->report(WARNING_LEVEL, ER_UNKNOWN_SYSTEM_VARIABLE, + "Unknown system variable 'SERVER_ID' on master, \ +maybe it is a very old master."); + } + if (master_res) + { mysql_free_result(master_res); - if (errmsg) - goto err; + master_res= NULL; } /* @@ -1008,23 +1072,52 @@ not always make sense; please check the if (*mysql->server_version == '3') goto err; - if ((*mysql->server_version == '4') && - !mysql_real_query(mysql, - STRING_WITH_LEN("SELECT @@GLOBAL.COLLATION_SERVER")) && - (master_res= mysql_store_result(mysql))) + if (*mysql->server_version == '4') { - if ((master_row= mysql_fetch_row(master_res)) && - strcmp(master_row[0], global_system_variables.collation_server->name)) + master_res= NULL; + if (!mysql_real_query(mysql, + STRING_WITH_LEN("SELECT @@GLOBAL.COLLATION_SERVER")) && + (master_res= mysql_store_result(mysql)) && + (master_row= mysql_fetch_row(master_res))) { - errmsg= "The slave I/O thread stops because master and slave have \ + if (strcmp(master_row[0], global_system_variables.collation_server->name)) + { + errmsg= "The slave I/O thread stops because master and slave have \ different values for the COLLATION_SERVER global variable. The values must \ be equal for replication to work"; - err_code= ER_SLAVE_FATAL_ERROR; - sprintf(err_buff, ER(err_code), errmsg); + err_code= ER_SLAVE_FATAL_ERROR; + sprintf(err_buff, ER(err_code), errmsg); + goto err; + } + } + else if (mysql_errno(mysql)) + { + if (is_network_error(mysql_errno(mysql))) + { + mi->report(WARNING_LEVEL, mysql_errno(mysql), + "Get master COLLATION_SERVER failed with error: %s", mysql_error(mysql)); + goto network_err; + } + + if (mysql_errno(mysql) != ER_UNKNOWN_SYSTEM_VARIABLE) + { + /* Fatal error */ + errmsg= "The slave I/O thread stops because a fatal error is encountered \ +when it try to get the value of COLLATION_SERVER global variable from master."; + err_code= ER_SLAVE_FATAL_ERROR; + sprintf(err_buff, ER(err_code), errmsg); + goto err; + } + else + mi->report(WARNING_LEVEL, ER_UNKNOWN_SYSTEM_VARIABLE, + "Unknown system variable 'COLLATION_SERVER' on master, \ +maybe it is a very old master."); + } + if (master_res) + { + mysql_free_result(master_res); + master_res= NULL; } - mysql_free_result(master_res); - if (errmsg) - goto err; } /* @@ -1042,35 +1135,62 @@ be equal for replication to work"; This check is only necessary for 4.x masters (and < 5.0.4 masters but those were alpha). */ - if ((*mysql->server_version == '4') && - !mysql_real_query(mysql, STRING_WITH_LEN("SELECT @@GLOBAL.TIME_ZONE")) && - (master_res= mysql_store_result(mysql))) - { - if ((master_row= mysql_fetch_row(master_res)) && - strcmp(master_row[0], - global_system_variables.time_zone->get_name()->ptr())) + if (*mysql->server_version == '4') + { + master_res= NULL; + if (!mysql_real_query(mysql, STRING_WITH_LEN("SELECT @@GLOBAL.TIME_ZONE")) && + (master_res= mysql_store_result(mysql)) && + (master_row= mysql_fetch_row(master_res))) { - errmsg= "The slave I/O thread stops because master and slave have \ + if (strcmp(master_row[0], + global_system_variables.time_zone->get_name()->ptr())) + { + errmsg= "The slave I/O thread stops because master and slave have \ different values for the TIME_ZONE global variable. The values must \ be equal for replication to work"; + err_code= ER_SLAVE_FATAL_ERROR; + sprintf(err_buff, ER(err_code), errmsg); + goto err; + } + } + else if (mysql_errno(mysql)) + { + if (is_network_error(mysql_errno(mysql))) + { + mi->report(WARNING_LEVEL, mysql_errno(mysql), + "Get master TIME_ZONE failed with error: %s", mysql_error(mysql)); + goto network_err; + } + /* Fatal error */ + errmsg= "The slave I/O thread stops because a fatal error is encountered \ +when it try to get the value of TIME_ZONE global variable from master."; err_code= ER_SLAVE_FATAL_ERROR; sprintf(err_buff, ER(err_code), errmsg); - } - mysql_free_result(master_res); - - if (errmsg) goto err; + } + if (master_res) + { + mysql_free_result(master_res); + master_res= NULL; + } } err: if (errmsg) { + if (master_res) + mysql_free_result(master_res); DBUG_ASSERT(err_code != 0); mi->report(ERROR_LEVEL, err_code, err_buff); DBUG_RETURN(1); } DBUG_RETURN(0); + +network_err: + if (master_res) + mysql_free_result(master_res); + DBUG_RETURN(2); } /* @@ -2372,6 +2492,7 @@ pthread_handler_t handle_slave_io(void * char llbuff[22]; uint retry_count; bool suppress_warnings; + int ret; #ifndef DBUG_OFF uint retry_count_reg= 0, retry_count_dump= 0, retry_count_event= 0; #endif @@ -2451,8 +2572,22 @@ connected: mi->slave_running= MYSQL_SLAVE_RUN_CONNECT; thd->slave_net = &mysql->net; thd_proc_info(thd, "Checking master version"); - if (get_master_version_and_clock(mysql, mi)) + ret= get_master_version_and_clock(mysql, mi); + if (ret == 1) + /* Fatal error */ goto err; + + if (ret == 2) + { + if (check_io_slave_killed(mi->io_thd, mi, NULL)) + goto err; + suppress_warnings= FALSE; + /* Try to reconnect because the error was caused by a transient network problem */ + if (try_to_reconnect(thd, mysql, mi, &retry_count, suppress_warnings, + reconnect_messages[SLAVE_RECON_ACT_REG])) + goto err; + goto connected; + } if (mi->rli.relay_log.description_event_for_queue->binlog_version > 1) { --===============1368599721== MIME-Version: 1.0 Content-Type: text/bzr-bundle; charset="us-ascii"; name="bzr/dao-gang.qu@stripped" Content-Transfer-Encoding: 7bit Content-Disposition: inline # Bazaar merge directive format 2 (Bazaar 0.90) # revision_id: dao-gang.qu@stripped # target_branch: file:///home/daogangq/mysql/bzrwork/bug45214/5.1-bt/ # testament_sha1: 18e6f1561fc17f3cec6f87f0b999a84ef32d9316 # timestamp: 2009-07-03 20:42:05 +0800 # base_revision_id: davi.arnaut@stripped\ # jrxxjz0fx90hj9lv # # Begin bundle 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 rjWa5yOBEr6IiJTsKaKCBH9xdyRThQkFfbkFwA== --===============1368599721==--