summaryrefslogtreecommitdiff
path: root/sql/slave.cc
diff options
context:
space:
mode:
authorunknown <knielsen@knielsen-hq.org>2014-03-12 00:14:49 +0100
committerunknown <knielsen@knielsen-hq.org>2014-03-12 00:14:49 +0100
commit8b9b7ec395df111f886224a565b63a1a312e5679 (patch)
treea44e2719f727964a854ed9c45e26e7314f6b62a4 /sql/slave.cc
parent2c2478b82260f5110ea2c5bed3c6c7bcd3558453 (diff)
downloadmariadb-git-8b9b7ec395df111f886224a565b63a1a312e5679.tar.gz
MDEV-5804: If same GTID is received on multiple master connections in multi-source replication, the event is double-executed causing corruption or replication failure
Some fixes, mainly to make it work in non-parallel replication mode also (--slave-parallel-threads=0). Patch should be fairly complete now.
Diffstat (limited to 'sql/slave.cc')
-rw-r--r--sql/slave.cc50
1 files changed, 39 insertions, 11 deletions
diff --git a/sql/slave.cc b/sql/slave.cc
index cf741ccedc0..79a2c4ccd25 100644
--- a/sql/slave.cc
+++ b/sql/slave.cc
@@ -3508,18 +3508,46 @@ static int exec_relay_log_event(THD* thd, Relay_log_info* rli,
*/
}
- /*
- For GTID, allocate a new sub_id for the given domain_id.
- The sub_id must be allocated in increasing order of binlog order.
- */
- if (typ == GTID_EVENT &&
- event_group_new_gtid(serial_rgi, static_cast<Gtid_log_event *>(ev)))
+ if (typ == GTID_EVENT)
{
- sql_print_error("Error reading relay log event: %s",
- "slave SQL thread aborted because of out-of-memory error");
- mysql_mutex_unlock(&rli->data_lock);
- delete ev;
- DBUG_RETURN(1);
+ Gtid_log_event *gev= static_cast<Gtid_log_event *>(ev);
+
+ /*
+ For GTID, allocate a new sub_id for the given domain_id.
+ The sub_id must be allocated in increasing order of binlog order.
+ */
+ if (event_group_new_gtid(serial_rgi, gev))
+ {
+ sql_print_error("Error reading relay log event: %s", "slave SQL thread "
+ "aborted because of out-of-memory error");
+ mysql_mutex_unlock(&rli->data_lock);
+ delete ev;
+ DBUG_RETURN(1);
+ }
+
+ if (opt_gtid_ignore_duplicates)
+ {
+ serial_rgi->current_gtid.domain_id= gev->domain_id;
+ serial_rgi->current_gtid.server_id= gev->server_id;
+ serial_rgi->current_gtid.seq_no= gev->seq_no;
+ int res= rpl_global_gtid_slave_state.check_duplicate_gtid
+ (&serial_rgi->current_gtid, serial_rgi);
+ if (res < 0)
+ {
+ sql_print_error("Error processing GTID event: %s", "slave SQL "
+ "thread aborted because of out-of-memory error");
+ mysql_mutex_unlock(&rli->data_lock);
+ delete ev;
+ DBUG_RETURN(1);
+ }
+ /*
+ If we need to skip this event group (because the GTID was already
+ applied), then do it using the code for slave_skip_counter, which
+ is able to handle skipping until the end of the event group.
+ */
+ if (!res)
+ rli->slave_skip_counter= 1;
+ }
}
serial_rgi->future_event_relay_log_pos= rli->future_event_relay_log_pos;