summaryrefslogtreecommitdiff
path: root/sql/slave.cc
diff options
context:
space:
mode:
Diffstat (limited to 'sql/slave.cc')
-rw-r--r--sql/slave.cc46
1 files changed, 35 insertions, 11 deletions
diff --git a/sql/slave.cc b/sql/slave.cc
index 2512954f805..b6611d44723 100644
--- a/sql/slave.cc
+++ b/sql/slave.cc
@@ -1715,7 +1715,14 @@ static int has_temporary_error(THD *thd)
DBUG_ENTER("has_temporary_error");
if (thd->is_fatal_error)
+ {
+ DBUG_PRINT("info", ("thd->net.last_errno: %s", ER(thd->net.last_errno)));
DBUG_RETURN(0);
+ }
+
+ DBUG_EXECUTE_IF("all_errors_are_temporary_errors",
+ if (thd->net.last_errno)
+ thd->net.last_errno= ER_LOCK_DEADLOCK;);
/*
Temporary error codes:
@@ -1724,7 +1731,10 @@ static int has_temporary_error(THD *thd)
*/
if (thd->net.last_errno == ER_LOCK_DEADLOCK ||
thd->net.last_errno == ER_LOCK_WAIT_TIMEOUT)
+ {
+ DBUG_PRINT("info", ("thd->net.last_errno: %s", ER(thd->net.last_errno)));
DBUG_RETURN(1);
+ }
#ifdef HAVE_NDB_BINLOG
/*
@@ -1795,9 +1805,6 @@ static int exec_relay_log_event(THD* thd, Relay_log_info* rli)
int const type_code= ev->get_type_code();
int exec_res= 0;
- /*
- */
-
DBUG_PRINT("exec_event",("%s(type_code: %d; server_id: %d)",
ev->get_type_str(), type_code, ev->server_id));
DBUG_PRINT("info", ("thd->options: %s%s; rli->last_event_start_time: %lu",
@@ -1806,7 +1813,6 @@ static int exec_relay_log_event(THD* thd, Relay_log_info* rli)
rli->last_event_start_time));
-
/*
Execute the event to change the database and update the binary
log coordinates, but first we set some data that is needed for
@@ -1854,10 +1860,13 @@ static int exec_relay_log_event(THD* thd, Relay_log_info* rli)
// EVENT_SKIP_NOT,
"not skipped",
// EVENT_SKIP_IGNORE,
- "skipped because event originated from this server",
+ "skipped because event should be ignored",
// EVENT_SKIP_COUNT
"skipped because event skip counter was non-zero"
};
+ DBUG_PRINT("info", ("OPTION_BEGIN: %d; IN_STMT: %d",
+ thd->options & OPTION_BEGIN ? 1 : 0,
+ rli->get_flag(Relay_log_info::IN_STMT)));
DBUG_PRINT("skip_event", ("%s event was %s",
ev->get_type_str(), explain[reason]));
#endif
@@ -1906,7 +1915,8 @@ static int exec_relay_log_event(THD* thd, Relay_log_info* rli)
}
if (slave_trans_retries)
{
- if (exec_res && has_temporary_error(thd))
+ int temp_err;
+ if (exec_res && (temp_err= has_temporary_error(thd)))
{
const char *errmsg;
/*
@@ -1954,15 +1964,19 @@ static int exec_relay_log_event(THD* thd, Relay_log_info* rli)
"the slave_transaction_retries variable.",
slave_trans_retries);
}
- else if (!((thd->options & OPTION_BEGIN) && opt_using_transactions))
+ else if (exec_res && !temp_err ||
+ (opt_using_transactions &&
+ rli->group_relay_log_pos == rli->event_relay_log_pos))
{
/*
- Only reset the retry counter if the event succeeded or
- failed with a non-transient error. On a successful event,
- the execution will proceed as usual; in the case of a
+ Only reset the retry counter if the entire group succeeded
+ or failed with a non-transient error. On a successful
+ event, the execution will proceed as usual; in the case of a
non-transient error, the slave will stop with an error.
*/
rli->trans_retries= 0; // restart from fresh
+ DBUG_PRINT("info", ("Resetting retry counter, rli->trans_retries: %lu",
+ rli->trans_retries));
}
}
DBUG_RETURN(exec_res);
@@ -2451,6 +2465,7 @@ pthread_handler_t handle_slave_sql(void *arg)
rli->ignore_log_space_limit= 0;
pthread_mutex_unlock(&rli->log_space_lock);
rli->trans_retries= 0; // start from "no error"
+ DBUG_PRINT("info", ("rli->trans_retries: %lu", rli->trans_retries));
if (init_relay_log_pos(rli,
rli->group_relay_log_name,
@@ -3582,7 +3597,16 @@ static Log_event* next_event(Relay_log_info* rli)
a new event and is queuing it; the false "0" will exist until SQL
finishes executing the new event; it will be look abnormal only if
the events have old timestamps (then you get "many", 0, "many").
- Transient phases like this can't really be fixed.
+
+ Transient phases like this can be fixed with implemeting
+ Heartbeat event which provides the slave the status of the
+ master at time the master does not have any new update to send.
+ Seconds_Behind_Master would be zero only when master has no
+ more updates in binlog for slave. The heartbeat can be sent
+ in a (small) fraction of slave_net_timeout. Until it's done
+ rli->last_master_timestamp is temporarely (for time of
+ waiting for the following event) reset whenever EOF is
+ reached.
*/
time_t save_timestamp= rli->last_master_timestamp;
rli->last_master_timestamp= 0;