summaryrefslogtreecommitdiff
path: root/sql/slave.cc
diff options
context:
space:
mode:
Diffstat (limited to 'sql/slave.cc')
-rw-r--r--sql/slave.cc140
1 files changed, 94 insertions, 46 deletions
diff --git a/sql/slave.cc b/sql/slave.cc
index 4b58816f409..e8119c6aea2 100644
--- a/sql/slave.cc
+++ b/sql/slave.cc
@@ -70,9 +70,10 @@ static inline bool sql_slave_killed(THD* thd,RELAY_LOG_INFO* rli);
static int count_relay_log_space(RELAY_LOG_INFO* rli);
static int init_slave_thread(THD* thd, SLAVE_THD_TYPE thd_type);
static int safe_connect(THD* thd, MYSQL* mysql, MASTER_INFO* mi);
-static int safe_reconnect(THD* thd, MYSQL* mysql, MASTER_INFO* mi);
+static int safe_reconnect(THD* thd, MYSQL* mysql, MASTER_INFO* mi,
+ bool suppress_warnings);
static int connect_to_master(THD* thd, MYSQL* mysql, MASTER_INFO* mi,
- bool reconnect);
+ bool reconnect, bool suppress_warnings);
static int safe_sleep(THD* thd, int sec, CHECK_KILLED_FUNC thread_killed,
void* thread_killed_arg);
static int request_table_dump(MYSQL* mysql, const char* db, const char* table);
@@ -1476,8 +1477,7 @@ static int init_slave_thread(THD* thd, SLAVE_THD_TYPE thd_type)
thd->system_thread = thd->bootstrap = 1;
thd->client_capabilities = 0;
my_net_init(&thd->net, 0);
- thd->net.timeout = slave_net_timeout;
- thd->max_packet_length=thd->net.max_packet;
+ thd->net.read_timeout = slave_net_timeout;
thd->master_access= ~0;
thd->priv_user = 0;
thd->slave_thread = 1;
@@ -1503,7 +1503,7 @@ static int init_slave_thread(THD* thd, SLAVE_THD_TYPE thd_type)
VOID(pthread_sigmask(SIG_UNBLOCK,&set,&thd->block_signals));
#endif
- if (thd->max_join_size == (ulong) ~0L)
+ if ((ulong) thd->variables.max_join_size == (ulong) HA_POS_ERROR)
thd->options |= OPTION_BIG_SELECTS;
if (thd_type == SLAVE_THD_SQL)
@@ -1515,6 +1515,7 @@ static int init_slave_thread(THD* thd, SLAVE_THD_TYPE thd_type)
DBUG_RETURN(0);
}
+
static int safe_sleep(THD* thd, int sec, CHECK_KILLED_FUNC thread_killed,
void* thread_killed_arg)
{
@@ -1548,7 +1549,8 @@ static int safe_sleep(THD* thd, int sec, CHECK_KILLED_FUNC thread_killed,
return 0;
}
-static int request_dump(MYSQL* mysql, MASTER_INFO* mi)
+static int request_dump(MYSQL* mysql, MASTER_INFO* mi,
+ bool *suppress_warnings)
{
char buf[FN_REFLEN + 10];
int len;
@@ -1567,7 +1569,10 @@ static int request_dump(MYSQL* mysql, MASTER_INFO* mi)
in the future, we should do a better error analysis, but for
now we just fill up the error log :-)
*/
- sql_print_error("Error on COM_BINLOG_DUMP: %s, will retry in %d secs",
+ if (mc_mysql_errno(mysql) == ER_NET_READ_INTERRUPTED)
+ *suppress_warnings= 1; // Suppress reconnect warning
+ else
+ sql_print_error("Error on COM_BINLOG_DUMP: %s, will retry in %d secs",
mc_mysql_error(mysql), master_connect_retry);
return 1;
}
@@ -1582,10 +1587,10 @@ static int request_table_dump(MYSQL* mysql, const char* db, const char* table)
uint table_len = (uint) strlen(table);
uint db_len = (uint) strlen(db);
if (table_len + db_len > sizeof(buf) - 2)
- {
- sql_print_error("request_table_dump: Buffer overrun");
- return 1;
- }
+ {
+ sql_print_error("request_table_dump: Buffer overrun");
+ return 1;
+ }
*p++ = db_len;
memcpy(p, db, db_len);
@@ -1603,7 +1608,24 @@ command");
return 0;
}
-static ulong read_event(MYSQL* mysql, MASTER_INFO *mi)
+/*
+ read one event from the master
+
+ SYNOPSIS
+ read_event()
+ mysql MySQL connection
+ mi Master connection information
+ suppress_warnings TRUE when a normal net read timeout has caused us to
+ try a reconnect. We do not want to print anything to
+ the error log in this case because this a anormal
+ event in an idle server.
+ RETURN VALUES
+ 'packet_error' Error
+ number Length of packet
+
+*/
+
+static ulong read_event(MYSQL* mysql, MASTER_INFO *mi, bool* suppress_warnings)
{
ulong len = packet_error;
@@ -1615,14 +1637,25 @@ static ulong read_event(MYSQL* mysql, MASTER_INFO *mi)
if (disconnect_slave_event_count && !(events_till_disconnect--))
return packet_error;
#endif
+ *suppress_warnings= 0;
len = mc_net_safe_read(mysql);
if (len == packet_error || (long) len < 1)
{
- sql_print_error("Error reading packet from server: %s (\
+ if (mc_mysql_errno(mysql) == ER_NET_READ_INTERRUPTED)
+ {
+ /*
+ We are trying a normal reconnect after a read timeout;
+ we suppress prints to .err file as long as the reconnect
+ happens without problems
+ */
+ *suppress_warnings= TRUE;
+ }
+ else
+ sql_print_error("Error reading packet from server: %s (\
server_errno=%d)",
- mc_mysql_error(mysql), mc_mysql_errno(mysql));
+ mc_mysql_error(mysql), mc_mysql_errno(mysql));
return packet_error;
}
@@ -1639,26 +1672,26 @@ server_errno=%d)",
return len - 1;
}
+
int check_expected_error(THD* thd, RELAY_LOG_INFO* rli, int expected_error)
{
- switch (expected_error)
- {
- case ER_NET_READ_ERROR:
- case ER_NET_ERROR_ON_WRITE:
- case ER_SERVER_SHUTDOWN:
- case ER_NEW_ABORTING_CONNECTION:
- my_snprintf(rli->last_slave_error, sizeof(rli->last_slave_error),
- "Slave: query '%s' partially completed on the master \
+ switch (expected_error) {
+ case ER_NET_READ_ERROR:
+ case ER_NET_ERROR_ON_WRITE:
+ case ER_SERVER_SHUTDOWN:
+ case ER_NEW_ABORTING_CONNECTION:
+ my_snprintf(rli->last_slave_error, sizeof(rli->last_slave_error),
+ "Slave: query '%s' partially completed on the master \
and was aborted. There is a chance that your master is inconsistent at this \
point. If you are sure that your master is ok, run this query manually on the\
slave and then restart the slave with SET SQL_SLAVE_SKIP_COUNTER=1;\
SLAVE START;", thd->query);
- rli->last_slave_errno = expected_error;
- sql_print_error("%s",rli->last_slave_error);
- return 1;
- default:
- return 0;
- }
+ rli->last_slave_errno = expected_error;
+ sql_print_error("%s",rli->last_slave_error);
+ return 1;
+ default:
+ return 0;
+ }
}
static int exec_relay_log_event(THD* thd, RELAY_LOG_INFO* rli)
@@ -1752,6 +1785,7 @@ slave_begin:
}
mi->io_thd = thd;
thd->thread_stack = (char*)&thd; // remember where our stack is
+ thd->store_globals();
threads.append(thd);
mi->slave_running = 1;
mi->abort_slave = 0;
@@ -1805,8 +1839,9 @@ connected:
while (!io_slave_killed(thd,mi))
{
+ bool suppress_warnings= 0;
thd->proc_info = "Requesting binlog dump";
- if (request_dump(mysql, mi))
+ if (request_dump(mysql, mi, &suppress_warnings))
{
sql_print_error("Failed on request_dump()");
if (io_slave_killed(thd,mi))
@@ -1837,10 +1872,12 @@ dump");
}
thd->proc_info = "Reconnecting after a failed dump request";
- sql_print_error("Slave I/O thread: failed dump request, \
+ if (!suppress_warnings)
+ sql_print_error("Slave I/O thread: failed dump request, \
reconnecting to try again, log '%s' at postion %s", IO_RPL_LOG_NAME,
- llstr(mi->master_log_pos,llbuff));
- if (safe_reconnect(thd, mysql, mi) || io_slave_killed(thd,mi))
+ llstr(mi->master_log_pos,llbuff));
+ if (safe_reconnect(thd, mysql, mi, suppress_warnings) ||
+ io_slave_killed(thd,mi))
{
sql_print_error("Slave I/O thread killed during or \
after reconnect");
@@ -1852,8 +1889,9 @@ after reconnect");
while (!io_slave_killed(thd,mi))
{
+ bool suppress_warnings= 0;
thd->proc_info = "Reading master update";
- ulong event_len = read_event(mysql, mi);
+ ulong event_len = read_event(mysql, mi, &suppress_warnings);
if (io_slave_killed(thd,mi))
{
sql_print_error("Slave I/O thread killed while reading event");
@@ -1867,7 +1905,7 @@ after reconnect");
sql_print_error("Log entry on master is longer than \
max_allowed_packet (%ld) on slave. Slave thread will be aborted. If the entry \
is correct, restart the server with a higher value of max_allowed_packet",
- max_allowed_packet);
+ thd->variables.max_allowed_packet);
goto err;
}
@@ -1886,10 +1924,12 @@ reconnect after a failed read");
goto err;
}
thd->proc_info = "Reconnecting after a failed read";
- sql_print_error("Slave I/O thread: Failed reading log event, \
+ if (!suppress_warnings)
+ sql_print_error("Slave I/O thread: Failed reading log event, \
reconnecting to retry, log '%s' position %s", IO_RPL_LOG_NAME,
- llstr(mi->master_log_pos, llbuff));
- if (safe_reconnect(thd, mysql, mi) || io_slave_killed(thd,mi))
+ llstr(mi->master_log_pos, llbuff));
+ if (safe_reconnect(thd, mysql, mi, suppress_warnings) ||
+ io_slave_killed(thd,mi))
{
sql_print_error("Slave I/O thread killed during or after a \
reconnect done to recover from failed read");
@@ -2005,6 +2045,7 @@ slave_begin:
THD_CHECK_SENTRY(thd);
thd->thread_stack = (char*)&thd; // remember where our stack is
thd->temporary_tables = rli->save_temporary_tables; // restore temp tables
+ thd->store_globals();
threads.append(thd);
rli->sql_thd = thd;
rli->slave_running = 1;
@@ -2383,7 +2424,7 @@ void end_relay_log_info(RELAY_LOG_INFO* rli)
/* try to connect until successful or slave killed */
static int safe_connect(THD* thd, MYSQL* mysql, MASTER_INFO* mi)
{
- return connect_to_master(thd, mysql, mi, 0);
+ return connect_to_master(thd, mysql, mi, 0, 0);
}
@@ -2393,7 +2434,7 @@ static int safe_connect(THD* thd, MYSQL* mysql, MASTER_INFO* mi)
*/
static int connect_to_master(THD* thd, MYSQL* mysql, MASTER_INFO* mi,
- bool reconnect)
+ bool reconnect, bool suppress_warnings)
{
int slave_was_killed;
int last_errno= -2; // impossible error
@@ -2406,11 +2447,13 @@ static int connect_to_master(THD* thd, MYSQL* mysql, MASTER_INFO* mi,
while (!(slave_was_killed = io_slave_killed(thd,mi)) &&
(reconnect ? mc_mysql_reconnect(mysql) != 0 :
!mc_mysql_connect(mysql, mi->host, mi->user, mi->password, 0,
- mi->port, 0, 0)))
+ mi->port, 0, 0,
+ thd->variables.net_read_timeout)))
{
/* Don't repeat last error */
if (mc_mysql_errno(mysql) != last_errno)
{
+ suppress_warnings= 0;
sql_print_error("Slave I/O thread: error connecting to master \
'%s@%s:%d': \
%s, last_errno=%d, retry in %d sec",mi->user,mi->host,mi->port,
@@ -2437,11 +2480,14 @@ static int connect_to_master(THD* thd, MYSQL* mysql, MASTER_INFO* mi,
if (!slave_was_killed)
{
if (reconnect)
- sql_print_error("Slave: connected to master '%s@%s:%d',\
+ {
+ if (!suppress_warnings)
+ sql_print_error("Slave: connected to master '%s@%s:%d',\
replication resumed in log '%s' at position %s", mi->user,
- mi->host, mi->port,
- IO_RPL_LOG_NAME,
- llstr(mi->master_log_pos,llbuff));
+ mi->host, mi->port,
+ IO_RPL_LOG_NAME,
+ llstr(mi->master_log_pos,llbuff));
+ }
else
{
change_rpl_status(RPL_IDLE_SLAVE,RPL_ACTIVE_SLAVE);
@@ -2462,11 +2508,13 @@ replication resumed in log '%s' at position %s", mi->user,
master_retry_count times
*/
-static int safe_reconnect(THD* thd, MYSQL* mysql, MASTER_INFO* mi)
+static int safe_reconnect(THD* thd, MYSQL* mysql, MASTER_INFO* mi,
+ bool suppress_warnings)
{
- return connect_to_master(thd, mysql, mi, 1);
+ return connect_to_master(thd, mysql, mi, 1, suppress_warnings);
}
+
int flush_relay_log_info(RELAY_LOG_INFO* rli)
{
register IO_CACHE* file = &rli->info_file;