diff options
Diffstat (limited to 'sql/sql_repl.cc')
-rw-r--r-- | sql/sql_repl.cc | 44 |
1 files changed, 37 insertions, 7 deletions
diff --git a/sql/sql_repl.cc b/sql/sql_repl.cc index 283078203ed..fcda6452e92 100644 --- a/sql/sql_repl.cc +++ b/sql/sql_repl.cc @@ -894,7 +894,8 @@ contains_all_slave_gtid(slave_connection_state *st, Gtid_list_log_event *glev) static int check_slave_start_position(THD *thd, slave_connection_state *st, const char **errormsg, rpl_gtid *error_gtid, - slave_connection_state *until_gtid_state) + slave_connection_state *until_gtid_state, + HASH *fake_gtid_hash) { uint32 i; int err; @@ -998,11 +999,30 @@ check_slave_start_position(THD *thd, slave_connection_state *st, &start_gtid) && start_gtid.seq_no > slave_gtid->seq_no) { + rpl_gtid *fake_gtid; /* Start replication within this domain at the first GTID that we logged ourselves after becoming a master. + + Remember that this starting point is in fact a "fake" GTID which may + not exists in the binlog, so that we do not complain about it in + --gtid-strict-mode. */ slave_gtid->server_id= global_system_variables.server_id; + if (!(fake_gtid= (rpl_gtid *)my_malloc(sizeof(*fake_gtid), MYF(0)))) + { + *errormsg= "Out of memory while checking slave start position"; + err= ER_OUT_OF_RESOURCES; + goto end; + } + *fake_gtid= *slave_gtid; + if (my_hash_insert(fake_gtid_hash, (uchar *)fake_gtid)) + { + my_free(fake_gtid); + *errormsg= "Out of memory while checking slave start position"; + err= ER_OUT_OF_RESOURCES; + goto end; + } } else if (mysql_bin_log.lookup_domain_in_binlog_state(slave_gtid->domain_id, &start_gtid)) @@ -1462,7 +1482,7 @@ send_event_to_slave(THD *thd, NET *net, String* const packet, ushort flags, enum_gtid_until_state *gtid_until_group, rpl_binlog_state *until_binlog_state, bool slave_gtid_strict_mode, rpl_gtid *error_gtid, - bool *send_fake_gtid_list) + bool *send_fake_gtid_list, HASH *fake_gtid_hash) { my_off_t pos; size_t len= packet->length(); @@ -1542,7 +1562,9 @@ send_event_to_slave(THD *thd, NET *net, String* const packet, ushort flags, if (event_gtid.server_id == gtid->server_id && event_gtid.seq_no >= gtid->seq_no) { - if (slave_gtid_strict_mode && event_gtid.seq_no > gtid->seq_no) + if (slave_gtid_strict_mode && event_gtid.seq_no > gtid->seq_no && + !my_hash_search(fake_gtid_hash, + (const uchar *)&event_gtid.domain_id, 0)) { /* In strict mode, it is an error if the slave requests to start @@ -1815,8 +1837,9 @@ void mysql_binlog_send(THD* thd, char* log_ident, my_off_t pos, enum_gtid_skip_type gtid_skip_group= GTID_SKIP_NOT; enum_gtid_until_state gtid_until_group= GTID_UNTIL_NOT_DONE; rpl_binlog_state until_binlog_state; - bool slave_gtid_strict_mode; + bool slave_gtid_strict_mode= false; bool send_fake_gtid_list= false; + HASH fake_gtid_hash; uint8 current_checksum_alg= BINLOG_CHECKSUM_ALG_UNDEF; int old_max_allowed_packet= thd->variables.max_allowed_packet; @@ -1830,6 +1853,9 @@ void mysql_binlog_send(THD* thd, char* log_ident, my_off_t pos, bzero((char*) &log,sizeof(log)); bzero(&error_gtid, sizeof(error_gtid)); + my_hash_init(&fake_gtid_hash, &my_charset_bin, 32, + offsetof(rpl_gtid, domain_id), sizeof(uint32), NULL, my_free, + HASH_UNIQUE); /* heartbeat_period from @master_heartbeat_period user variable */ @@ -1929,7 +1955,8 @@ void mysql_binlog_send(THD* thd, char* log_ident, my_off_t pos, goto err; } if ((error= check_slave_start_position(thd, >id_state, &errmsg, - &error_gtid, until_gtid_state))) + &error_gtid, until_gtid_state, + &fake_gtid_hash))) { my_errno= error; goto err; @@ -2234,7 +2261,7 @@ impossible position"; until_gtid_state, >id_until_group, &until_binlog_state, slave_gtid_strict_mode, &error_gtid, - &send_fake_gtid_list))) + &send_fake_gtid_list, &fake_gtid_hash))) { errmsg= tmp_msg; goto err; @@ -2440,7 +2467,8 @@ impossible position"; >id_skip_group, until_gtid_state, >id_until_group, &until_binlog_state, slave_gtid_strict_mode, &error_gtid, - &send_fake_gtid_list))) + &send_fake_gtid_list, + &fake_gtid_hash))) { errmsg= tmp_msg; goto err; @@ -2530,6 +2558,7 @@ impossible position"; end: end_io_cache(&log); mysql_file_close(file, MYF(MY_WME)); + my_hash_free(&fake_gtid_hash); RUN_HOOK(binlog_transmit, transmit_stop, (thd, flags)); my_eof(thd); @@ -2600,6 +2629,7 @@ err: mysql_mutex_unlock(&LOCK_thread_count); if (file >= 0) mysql_file_close(file, MYF(MY_WME)); + my_hash_free(&fake_gtid_hash); thd->variables.max_allowed_packet= old_max_allowed_packet; my_message(my_errno, error_text, MYF(0)); |