Commit 75dc2671 authored by Kristian Nielsen's avatar Kristian Nielsen

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.
parent e7cb032e
......@@ -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);
......
......@@ -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();
}
......
......@@ -668,6 +668,13 @@ struct rpl_group_info
/* Needs room for "Gtid D-S-N\x00". */
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.
......
......@@ -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);
......
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