summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKristian Nielsen <knielsen@knielsen-hq.org>2015-10-22 10:28:51 +0200
committerKristian Nielsen <knielsen@knielsen-hq.org>2015-11-13 10:24:53 +0100
commit75dc2671011ba53e4f4531752c213ced7f9012ff (patch)
tree1fda725bc4315c4190a9c39917791788788b05ef
parente7cb032e560e14865941ecdcb553cd3aba856b68 (diff)
downloadmariadb-git-75dc2671011ba53e4f4531752c213ced7f9012ff.tar.gz
Change Seconds_behind_master to be updated only at commit in parallel replication
Before, the Seconds_behind_master was updated already when an event was queued for a worker thread to execute later. This might lead users to interpret a low value as the slave being almost up to date with the master, while in reality there might still be lots and lots of events still queued up waiting to be applied by the slave. See https://lists.launchpad.net/maria-developers/msg08958.html for more detailed discussions.
-rw-r--r--sql/rpl_parallel.cc3
-rw-r--r--sql/rpl_rli.cc13
-rw-r--r--sql/rpl_rli.h7
-rw-r--r--sql/slave.cc7
4 files changed, 29 insertions, 1 deletions
diff --git a/sql/rpl_parallel.cc b/sql/rpl_parallel.cc
index cc5da77303c..920442cb76d 100644
--- a/sql/rpl_parallel.cc
+++ b/sql/rpl_parallel.cc
@@ -44,6 +44,9 @@ rpt_handle_event(rpl_parallel_thread::queued_event *qev,
rgi->event_relay_log_pos= qev->event_relay_log_pos;
rgi->future_event_relay_log_pos= qev->future_event_relay_log_pos;
strcpy(rgi->future_event_master_log_name, qev->future_event_master_log_name);
+ if (!(ev->is_artificial_event() || ev->is_relay_log_event() ||
+ (ev->when == 0)))
+ rgi->last_master_timestamp= ev->when + (time_t)ev->exec_time;
mysql_mutex_lock(&rli->data_lock);
/* Mutex will be released in apply_event_and_update_pos(). */
err= apply_event_and_update_pos(ev, thd, rgi, rpt);
diff --git a/sql/rpl_rli.cc b/sql/rpl_rli.cc
index 8a2a55fcde0..3b2fea93c3b 100644
--- a/sql/rpl_rli.cc
+++ b/sql/rpl_rli.cc
@@ -1001,6 +1001,18 @@ void Relay_log_info::inc_group_relay_log_pos(ulonglong log_pos,
else if (group_master_log_pos < log_pos)
group_master_log_pos= log_pos;
}
+
+ /*
+ In the parallel case, we only update the Seconds_Behind_Master at the
+ end of a transaction. In the non-parallel case, the value is updated as
+ soon as an event is read from the relay log; however this would be too
+ confusing for the user, seeing the slave reported as up-to-date when
+ potentially thousands of events are still queued up for worker threads
+ waiting for execution.
+ */
+ if (rgi->last_master_timestamp &&
+ rgi->last_master_timestamp > last_master_timestamp)
+ last_master_timestamp= rgi->last_master_timestamp;
}
else
{
@@ -1630,6 +1642,7 @@ rpl_group_info::reinit(Relay_log_info *rli)
row_stmt_start_timestamp= 0;
long_find_row_note_printed= false;
did_mark_start_commit= false;
+ last_master_timestamp = 0;
gtid_ignore_duplicate_state= GTID_DUPLICATE_NULL;
commit_orderer.reinit();
}
diff --git a/sql/rpl_rli.h b/sql/rpl_rli.h
index 2d92f384ef3..1e8bb66ffbe 100644
--- a/sql/rpl_rli.h
+++ b/sql/rpl_rli.h
@@ -669,6 +669,13 @@ struct rpl_group_info
char gtid_info_buf[5+10+1+10+1+20+1];
/*
+ The timestamp, from the master, of the commit event.
+ Used to do delayed update of rli->last_master_timestamp, for getting
+ reasonable values out of Seconds_Behind_Master in SHOW SLAVE STATUS.
+ */
+ time_t last_master_timestamp;
+
+ /*
Information to be able to re-try an event group in case of a deadlock or
other temporary error.
*/
diff --git a/sql/slave.cc b/sql/slave.cc
index 5af48b6a793..32f384d4e22 100644
--- a/sql/slave.cc
+++ b/sql/slave.cc
@@ -3500,8 +3500,13 @@ static int exec_relay_log_event(THD* thd, Relay_log_info* rli,
If it is an artificial event, or a relay log event (IO thread generated
event) or ev->when is set to 0, we don't update the
last_master_timestamp.
+
+ In parallel replication, we might queue a large number of events, and
+ the user might be surprised to see a claim that the slave is up to date
+ long before those queued events are actually executed.
*/
- if (!(ev->is_artificial_event() || ev->is_relay_log_event() || (ev->when == 0)))
+ if (opt_slave_parallel_threads == 0 &&
+ !(ev->is_artificial_event() || ev->is_relay_log_event() || (ev->when == 0)))
{
rli->last_master_timestamp= ev->when + (time_t) ev->exec_time;
DBUG_ASSERT(rli->last_master_timestamp >= 0);