Commit 081926f3 authored by unknown's avatar unknown

MDEV-6188: master_retry_count (ignored if disconnect happens on SET master_heartbeat_period)

That particular part of slave connect to master was missing code to handle
retry in case of network errors. The same problem is present in MySQL 5.5, but
fixed in MySQL 5.6.

Fixed with this patch, by adding the code (mostly identical to MySQL 5.6), and
also adding a test case.

I checked other queries done towards master during slave connect, and they now
all seem to handle reconnect in case of network failures.
parent 5f7c2969
include/master-slave.inc
[connection master]
include/stop_slave.inc
set @restore_slave_net_timeout= @@global.slave_net_timeout;
set @@global.slave_net_timeout= 10;
show status like 'Slave_heartbeat_period';;
Variable_name Slave_heartbeat_period
Value 60.000
SET @save_dbug= @@GLOBAL.debug_dbug;
SET GLOBAL debug_dbug="+d,simulate_slave_heartbeat_network_error";
CALL mtr.add_suppression('SET @master_heartbeat_period to master failed with error');
CALL mtr.add_suppression('Master command COM_REGISTER_SLAVE failed: failed registering on master, reconnecting to try again');
include/start_slave.inc
drop table if exists t1;
CREATE TABLE t1 (a INT PRIMARY KEY);
INSERT INTO t1 VALUES (1);
SELECT * FROM t1;
a
1
drop table t1;
include/stop_slave.inc
SET GLOBAL debug_dbug=@save_dbug;
set @@global.slave_net_timeout= @restore_slave_net_timeout;
include/start_slave.inc
include/rpl_end.inc
# Testing master to slave heartbeat protocol, test cases that need debug build.
--source include/master-slave.inc
--source include/have_debug.inc
connection slave;
--source include/stop_slave.inc
set @restore_slave_net_timeout= @@global.slave_net_timeout;
--disable_warnings
set @@global.slave_net_timeout= 10;
--enable_warnings
###
### Checking the range
###
#
# default period slave_net_timeout/2
#
--query_vertical show status like 'Slave_heartbeat_period';
SET @save_dbug= @@GLOBAL.debug_dbug;
SET GLOBAL debug_dbug="+d,simulate_slave_heartbeat_network_error";
CALL mtr.add_suppression('SET @master_heartbeat_period to master failed with error');
CALL mtr.add_suppression('Master command COM_REGISTER_SLAVE failed: failed registering on master, reconnecting to try again');
--source include/start_slave.inc
connection master;
--disable_warnings
drop table if exists t1;
--enable_warnings
CREATE TABLE t1 (a INT PRIMARY KEY);
INSERT INTO t1 VALUES (1);
sync_slave_with_master;
--connection slave
SELECT * FROM t1;
connection master;
drop table t1;
connection slave;
--source include/stop_slave.inc
--disable_warnings
SET GLOBAL debug_dbug=@save_dbug;
set @@global.slave_net_timeout= @restore_slave_net_timeout;
--enable_warnings
--source include/start_slave.inc
--source include/rpl_end.inc
...@@ -1630,15 +1630,35 @@ when it try to get the value of TIME_ZONE global variable from master."; ...@@ -1630,15 +1630,35 @@ when it try to get the value of TIME_ZONE global variable from master.";
llstr((ulonglong) (mi->heartbeat_period*1000000000UL), llbuf); llstr((ulonglong) (mi->heartbeat_period*1000000000UL), llbuf);
sprintf(query, query_format, llbuf); sprintf(query, query_format, llbuf);
if (mysql_real_query(mysql, query, strlen(query)) DBUG_EXECUTE_IF("simulate_slave_heartbeat_network_error",
&& !check_io_slave_killed(mi->io_thd, mi, NULL)) { static ulong dbug_count= 0;
if (++dbug_count < 3)
goto heartbeat_network_error;
});
if (mysql_real_query(mysql, query, strlen(query)))
{ {
errmsg= "The slave I/O thread stops because SET @master_heartbeat_period " if (check_io_slave_killed(mi->io_thd, mi, NULL))
"on master failed."; goto slave_killed_err;
err_code= ER_SLAVE_FATAL_ERROR;
sprintf(err_buff, "%s Error: %s", errmsg, mysql_error(mysql)); if (is_network_error(mysql_errno(mysql)))
mysql_free_result(mysql_store_result(mysql)); {
goto err; IF_DBUG(heartbeat_network_error: , )
mi->report(WARNING_LEVEL, mysql_errno(mysql),
"SET @master_heartbeat_period to master failed with error: %s",
mysql_error(mysql));
mysql_free_result(mysql_store_result(mysql));
goto network_err;
}
else
{
/* Fatal error */
errmsg= "The slave I/O thread stops because a fatal error is encountered "
"when it tries to SET @master_heartbeat_period on master.";
err_code= ER_SLAVE_FATAL_ERROR;
sprintf(err_buff, "%s Error: %s", errmsg, mysql_error(mysql));
mysql_free_result(mysql_store_result(mysql));
goto err;
}
} }
mysql_free_result(mysql_store_result(mysql)); mysql_free_result(mysql_store_result(mysql));
} }
......
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