diff options
-rw-r--r-- | mysql-test/suite/rpl/r/rpl_gtid_nobinlog.result | 6 | ||||
-rw-r--r-- | mysql-test/suite/rpl/t/rpl_gtid_nobinlog.test | 6 | ||||
-rw-r--r-- | sql/sql_repl.cc | 44 | ||||
-rw-r--r-- | storage/federatedx/ha_federatedx.cc | 1 |
4 files changed, 49 insertions, 8 deletions
diff --git a/mysql-test/suite/rpl/r/rpl_gtid_nobinlog.result b/mysql-test/suite/rpl/r/rpl_gtid_nobinlog.result index bc7be2a30b7..d6a826ffaaa 100644 --- a/mysql-test/suite/rpl/r/rpl_gtid_nobinlog.result +++ b/mysql-test/suite/rpl/r/rpl_gtid_nobinlog.result @@ -1,10 +1,14 @@ include/rpl_init.inc [topology=1->2] +SET @old_strict= @@GLOBAL.gtid_strict_mode; +SET GLOBAL gtid_strict_mode= 1; select @@global.log_slave_updates; @@global.log_slave_updates 0 CREATE TABLE t1 (a INT PRIMARY KEY, b INT); INSERT INTO t1 VALUES (1, 1); INSERT INTO t1 VALUES (2, 1); +SET @old_strict= @@GLOBAL.gtid_strict_mode; +SET GLOBAL gtid_strict_mode= 1; select @@global.log_slave_updates; @@global.log_slave_updates 0 @@ -47,5 +51,7 @@ a b 4 2 5 1 6 1 +SET GLOBAL gtid_strict_mode= @old_strict; +SET GLOBAL gtid_strict_mode= @old_strict; DROP TABLE t1; include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_gtid_nobinlog.test b/mysql-test/suite/rpl/t/rpl_gtid_nobinlog.test index 9c9c8090eba..ceb79062155 100644 --- a/mysql-test/suite/rpl/t/rpl_gtid_nobinlog.test +++ b/mysql-test/suite/rpl/t/rpl_gtid_nobinlog.test @@ -3,6 +3,8 @@ --source include/have_binlog_format_statement.inc --connection server_1 +SET @old_strict= @@GLOBAL.gtid_strict_mode; +SET GLOBAL gtid_strict_mode= 1; select @@global.log_slave_updates; CREATE TABLE t1 (a INT PRIMARY KEY, b INT); @@ -11,6 +13,8 @@ INSERT INTO t1 VALUES (2, 1); --save_master_pos --connection server_2 +SET @old_strict= @@GLOBAL.gtid_strict_mode; +SET GLOBAL gtid_strict_mode= 1; select @@global.log_slave_updates; --sync_with_master @@ -49,8 +53,10 @@ START SLAVE; SELECT * FROM t1 ORDER BY a; # Cleanup. +SET GLOBAL gtid_strict_mode= @old_strict; --connection server_1 +SET GLOBAL gtid_strict_mode= @old_strict; DROP TABLE t1; --source include/rpl_end.inc 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)); diff --git a/storage/federatedx/ha_federatedx.cc b/storage/federatedx/ha_federatedx.cc index a7f2d887952..1c9db78da4f 100644 --- a/storage/federatedx/ha_federatedx.cc +++ b/storage/federatedx/ha_federatedx.cc @@ -539,7 +539,6 @@ static int parse_url_error(FEDERATEDX_SHARE *share, TABLE_SHARE *table_s, int get_connection(MEM_ROOT *mem_root, FEDERATEDX_SHARE *share) { int error_num= ER_FOREIGN_SERVER_DOESNT_EXIST; - char error_buffer[FEDERATEDX_QUERY_BUFFER_SIZE]; FOREIGN_SERVER *server, server_buffer; DBUG_ENTER("ha_federatedx::get_connection"); |