diff options
author | unknown <knielsen@knielsen-hq.org> | 2014-03-12 00:14:49 +0100 |
---|---|---|
committer | unknown <knielsen@knielsen-hq.org> | 2014-03-12 00:14:49 +0100 |
commit | 8b9b7ec395df111f886224a565b63a1a312e5679 (patch) | |
tree | a44e2719f727964a854ed9c45e26e7314f6b62a4 /sql/slave.cc | |
parent | 2c2478b82260f5110ea2c5bed3c6c7bcd3558453 (diff) | |
download | mariadb-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.cc | 50 |
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; |