summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrandon Nesterenko <brandon.nesterenko@mariadb.com>2021-11-09 08:58:03 -0700
committerBrandon Nesterenko <brandon.nesterenko@mariadb.com>2021-11-09 08:58:03 -0700
commit1f2c7951d7a0c4e96ca6708b9b0952e6f13677b9 (patch)
tree41509b55ada938b431cb19644e4f37fd85c23a86
parentfa12a418bec21ae98c0d177d7065c1284a5c08b0 (diff)
downloadmariadb-git-10.7-MDEV-20119-v2.tar.gz
Stash holder10.7-MDEV-20119-v2
-rw-r--r--client/mysqlbinlog.cc157
-rw-r--r--mysql-test/suite/binlog/t/binlog_mysqlbinlog_gtid_ignore.test420
-rw-r--r--sql/rpl_gtid.cc38
-rw-r--r--sql/rpl_gtid.h13
4 files changed, 440 insertions, 188 deletions
diff --git a/client/mysqlbinlog.cc b/client/mysqlbinlog.cc
index ec1469b0c46..86bccc4cc90 100644
--- a/client/mysqlbinlog.cc
+++ b/client/mysqlbinlog.cc
@@ -154,7 +154,8 @@ static ulonglong start_position= BIN_LOG_HEADER_SIZE,
#define stop_position_mot ((my_off_t)stop_position)
static Gtid_event_filter *gtid_event_filter= NULL;
-static Domain_gtid_event_filter *domain_gtid_filter= NULL;
+static Domain_gtid_event_filter *domain_window_gtid_filter= NULL;
+static Domain_gtid_event_filter *domain_id_exclusivity_gtid_filter= NULL;
static Server_gtid_event_filter *server_gtid_filter= NULL;
static char *start_datetime_str, *stop_datetime_str;
@@ -997,7 +998,7 @@ static bool print_row_event(PRINT_EVENT_INFO *print_event_info, Log_event *ev,
*/
static inline my_bool is_gtid_filtering_enabled()
{
- return domain_gtid_filter != NULL;
+ return domain_window_gtid_filter || domain_id_exclusivity_gtid_filter;
}
/*
@@ -1049,11 +1050,11 @@ Exit_status process_event(PRINT_EVENT_INFO *print_event_info, Log_event *ev,
#endif
/* Run time estimation of the output window configuration. */
- if (ev_type == GTID_LIST_EVENT && is_gtid_filtering_enabled())
+ if (ev_type == GTID_LIST_EVENT && domain_window_gtid_filter)
{
Gtid_list_log_event *glev= (Gtid_list_log_event *)ev;
- size_t n_start_gtid_ranges= domain_gtid_filter->get_num_start_gtids();
- rpl_gtid *start_gtids= domain_gtid_filter->get_start_gtids();
+ size_t n_start_gtid_ranges= domain_window_gtid_filter->get_num_start_gtids();
+ rpl_gtid *start_gtids= domain_window_gtid_filter->get_start_gtids();
for (size_t i= 0; i < n_start_gtid_ranges; i++)
{
for (size_t k= 0; k < glev->count; k++)
@@ -1072,8 +1073,8 @@ Exit_status process_event(PRINT_EVENT_INFO *print_event_info, Log_event *ev,
}
}
}
- size_t n_stop_gtid_ranges= domain_gtid_filter->get_num_stop_gtids();
- rpl_gtid *stop_gtids= domain_gtid_filter->get_stop_gtids();
+ size_t n_stop_gtid_ranges= domain_window_gtid_filter->get_num_stop_gtids();
+ rpl_gtid *stop_gtids= domain_window_gtid_filter->get_stop_gtids();
for (size_t i= 0; i < n_stop_gtid_ranges; i++)
{
for (size_t k= 0; k < glev->count; k++)
@@ -1100,7 +1101,7 @@ Exit_status process_event(PRINT_EVENT_INFO *print_event_info, Log_event *ev,
If the binlog output should be filtered using GTIDs, test the new event
group to see if its events should be written or ignored.
*/
- if (ev_type == GTID_EVENT && gtid_event_filter)
+ if (ev_type == GTID_EVENT && is_gtid_filtering_enabled())
{
Gtid_log_event *gle= (Gtid_log_event*) ev;
rpl_gtid gtid;
@@ -1148,7 +1149,8 @@ Exit_status process_event(PRINT_EVENT_INFO *print_event_info, Log_event *ev,
events.
*/
if (ev_type != ROTATE_EVENT &&
- !ev->is_event_group_active() && is_server_id_excluded(ev->server_id))
+ is_server_id_excluded(ev->server_id))
+ //!ev->is_event_group_active() && is_server_id_excluded(ev->server_id))
//server_id && (server_id != ev->server_id))
goto end;
}
@@ -1561,7 +1563,7 @@ Exit_status process_event(PRINT_EVENT_INFO *print_event_info, Log_event *ev,
If all filters have finished, e.g. all --stop-position GTIDs have been hit,
and the last event group has finished printing, then we are finished
*/
- if (domain_gtid_filter && domain_gtid_filter->has_finished() &&
+ if (domain_window_gtid_filter && domain_window_gtid_filter->has_finished() &&
!Log_event::is_event_group_active())
retval= OK_STOP;
@@ -1989,7 +1991,24 @@ static void cleanup()
my_free(server_id_str);
free_root(&glob_root, MYF(0));
- delete gtid_event_filter;
+ if (gtid_event_filter)
+ {
+ delete gtid_event_filter;
+ }
+ else
+ {
+ /*
+ If there was an error during input parsing, gtid_event_filter will not
+ be set, so we need to ensure the comprising filters are cleaned up
+ properly.
+ */
+ if (domain_id_exclusivity_gtid_filter)
+ delete domain_id_exclusivity_gtid_filter;
+ if (domain_window_gtid_filter)
+ delete domain_window_gtid_filter;
+ if (server_gtid_filter)
+ delete server_gtid_filter;
+ }
delete binlog_filter;
delete glob_description_event;
@@ -2131,24 +2150,6 @@ static void extend_main_gtid_event_filter(Gtid_event_filter *new_filter)
new Intersecting_gtid_event_filter(gtid_event_filter, new_filter);
}
-static void ensure_server_filter_initialized()
-{
- if (server_gtid_filter == NULL)
- {
- server_gtid_filter= new Server_gtid_event_filter();
- extend_main_gtid_event_filter(server_gtid_filter);
- }
-}
-
-static void ensure_domain_filter_initialized()
-{
- if (domain_gtid_filter == NULL)
- {
- domain_gtid_filter= new Domain_gtid_event_filter();
- extend_main_gtid_event_filter(domain_gtid_filter);
- }
-}
-
extern "C" my_bool
get_one_option(const struct my_option *opt, const char *argument, const char *filename)
{
@@ -2335,8 +2336,9 @@ get_one_option(const struct my_option *opt, const char *argument, const char *fi
case OPT_STOP_POSITION:
{
/* Stop position was already specified, so reset it and use the new list */
- if (domain_gtid_filter && domain_gtid_filter->get_num_stop_gtids() > 0)
- domain_gtid_filter->clear_stop_gtids();
+ if (domain_window_gtid_filter &&
+ domain_window_gtid_filter->get_num_stop_gtids() > 0)
+ domain_window_gtid_filter->clear_stop_gtids();
uint32 n_stop_gtid_ranges= 0;
rpl_gtid *stop_gtids= gtid_parse_string_to_list(stop_pos_str, strlen(stop_pos_str),
@@ -2362,11 +2364,13 @@ get_one_option(const struct my_option *opt, const char *argument, const char *fi
else if (n_stop_gtid_ranges > 0)
{
uint32 gtid_idx;
- ensure_domain_filter_initialized();
+ if (domain_window_gtid_filter == NULL)
+ domain_window_gtid_filter= new Domain_gtid_event_filter();
+
for (gtid_idx = 0; gtid_idx < n_stop_gtid_ranges; gtid_idx++)
{
rpl_gtid *stop_gtid= &stop_gtids[gtid_idx];
- if (domain_gtid_filter->add_stop_gtid(stop_gtid))
+ if (domain_window_gtid_filter->add_stop_gtid(stop_gtid))
{
my_free(stop_gtids);
return 1;
@@ -2383,8 +2387,9 @@ get_one_option(const struct my_option *opt, const char *argument, const char *fi
case 'j':
{
/* Start position was already specified, so reset it and use the new list */
- if (domain_gtid_filter && domain_gtid_filter->get_num_start_gtids() > 0)
- domain_gtid_filter->clear_start_gtids();
+ if (domain_window_gtid_filter &&
+ domain_window_gtid_filter->get_num_start_gtids() > 0)
+ domain_window_gtid_filter->clear_start_gtids();
uint32 n_start_gtid_ranges= 0;
rpl_gtid *start_gtids= gtid_parse_string_to_list(
@@ -2398,6 +2403,9 @@ get_one_option(const struct my_option *opt, const char *argument, const char *fi
No GTIDs specified in OPT_START_POSITION specification. Treat the value
as a singular index.
*/
+ if (domain_window_gtid_filter == NULL)
+ domain_window_gtid_filter= new Domain_gtid_event_filter();
+
start_position= my_strtoll10(start_pos_str, &end_ptr, &err);
if (err || *end_ptr)
@@ -2411,11 +2419,13 @@ get_one_option(const struct my_option *opt, const char *argument, const char *fi
else if (n_start_gtid_ranges > 0)
{
uint32 gtid_idx;
- ensure_domain_filter_initialized();
+ if (domain_window_gtid_filter == NULL)
+ domain_window_gtid_filter= new Domain_gtid_event_filter();
+
for (gtid_idx = 0; gtid_idx < n_start_gtid_ranges; gtid_idx++)
{
rpl_gtid *start_gtid= &start_gtids[gtid_idx];
- if (domain_gtid_filter->add_start_gtid(start_gtid))
+ if (domain_window_gtid_filter->add_start_gtid(start_gtid))
{
my_free(start_gtids);
return 1;
@@ -2437,13 +2447,15 @@ get_one_option(const struct my_option *opt, const char *argument, const char *fi
if (domain_ids == NULL || n_ids == 0)
{
- sql_print_error("Value for --ignore-domain-ids is invalid. Should be a "
+ sql_print_error("Input for --ignore-domain-ids is invalid. Should be a "
"list of positive integers");
return 1;
}
- ensure_domain_filter_initialized();
- if (domain_gtid_filter->set_blacklist(domain_ids, n_ids))
+ if (domain_id_exclusivity_gtid_filter == NULL)
+ domain_id_exclusivity_gtid_filter= new Domain_gtid_event_filter();
+
+ if (domain_id_exclusivity_gtid_filter->set_blacklist(domain_ids, n_ids))
{
my_free(domain_ids);
/* TODO Set_blacklist should write the specific error*/
@@ -2462,18 +2474,17 @@ get_one_option(const struct my_option *opt, const char *argument, const char *fi
if (domain_ids == NULL || n_ids == 0)
{
- sql_print_error("Value for --do-domain-ids is invalid. Should be a "
+ sql_print_error("Input for --do-domain-ids is invalid. Should be a "
"list of positive integers");
return 1;
}
- ensure_domain_filter_initialized();
- if (domain_gtid_filter->set_whitelist(domain_ids, n_ids))
+ if (domain_id_exclusivity_gtid_filter == NULL)
+ domain_id_exclusivity_gtid_filter= new Domain_gtid_event_filter();
+
+ if (domain_id_exclusivity_gtid_filter->set_whitelist(domain_ids, n_ids))
{
my_free(domain_ids);
- /* TODO set_whitelist should write the specific error*/
- sql_print_error(
- "Cannot combine --ignore-domain-ids with --do-domain-ids");
return 1;
}
my_free(domain_ids);
@@ -2487,18 +2498,17 @@ get_one_option(const struct my_option *opt, const char *argument, const char *fi
if (server_ids == NULL || n_ids == 0)
{
- sql_print_error("Value for --ignore-server-ids is invalid. Should be a "
+ sql_print_error("Input for --ignore-server-ids is invalid. Should be a "
"list of positive integers");
return 1;
}
- ensure_server_filter_initialized();
+ if (server_gtid_filter == NULL)
+ server_gtid_filter= new Server_gtid_event_filter();
+
if (server_gtid_filter->set_blacklist(server_ids, n_ids))
{
my_free(server_ids);
- /* TODO set_whitelist should write the specific error*/
- sql_print_error(
- "An id specified in --ignore-server-ids already has a filtering rule");
return 1;
}
my_free(server_ids);
@@ -2512,18 +2522,17 @@ get_one_option(const struct my_option *opt, const char *argument, const char *fi
if (server_ids == NULL || n_ids == 0)
{
- sql_print_error("Value for --do-server-ids is invalid. Should be a "
+ sql_print_error("Input for --do-server-ids is invalid. Should be a "
"list of positive integers");
return 1;
}
- ensure_server_filter_initialized();
+ if (server_gtid_filter == NULL)
+ server_gtid_filter= new Server_gtid_event_filter();
+
if (server_gtid_filter->set_whitelist(server_ids, n_ids))
{
my_free(server_ids);
- /* TODO set_whitelist should write the specific error*/
- sql_print_error(
- "An id specified in --do-server-ids already has a filtering rule");
return 1;
}
my_free(server_ids);
@@ -2537,18 +2546,17 @@ get_one_option(const struct my_option *opt, const char *argument, const char *fi
if (server_ids == NULL || n_ids == 0)
{
- sql_print_error("Value for --server-id is invalid. Should be a "
+ sql_print_error("Input for --server-id is invalid. Should be a "
"list of positive integers");
return 1;
}
- ensure_server_filter_initialized();
+ if (server_gtid_filter == NULL)
+ server_gtid_filter= new Server_gtid_event_filter();
+
if (server_gtid_filter->set_whitelist(server_ids, n_ids))
{
my_free(server_ids);
- /* TODO set_whitelist should write the specific error*/
- sql_print_error(
- "An id specified in --server-id already has a filtering rule");
return 1;
}
my_free(server_ids);
@@ -2565,7 +2573,6 @@ get_one_option(const struct my_option *opt, const char *argument, const char *fi
return 0;
}
-
static int parse_args(int *argc, char*** argv)
{
int ho_error;
@@ -2587,10 +2594,22 @@ static int parse_args(int *argc, char*** argv)
start_position= UINT_MAX32;
}
- if (domain_gtid_filter)
+ if (domain_window_gtid_filter)
+ {
+ Log_event::enable_event_group_filtering();
+ domain_window_gtid_filter->set_gtid_strict_mode(opt_gtid_strict_mode);
+ extend_main_gtid_event_filter(domain_window_gtid_filter);
+ }
+
+ if(domain_id_exclusivity_gtid_filter)
{
Log_event::enable_event_group_filtering();
- domain_gtid_filter->set_gtid_strict_mode(opt_gtid_strict_mode);
+ extend_main_gtid_event_filter(domain_id_exclusivity_gtid_filter);
+ }
+
+ if(server_gtid_filter)
+ {
+ extend_main_gtid_event_filter(server_gtid_filter);
}
return 0;
}
@@ -2773,7 +2792,7 @@ static Exit_status check_master_version()
goto err;
}
- if (domain_gtid_filter && domain_gtid_filter->get_num_start_gtids() > 0)
+ if (domain_window_gtid_filter && domain_window_gtid_filter->get_num_start_gtids() > 0)
{
char str_buf[256];
String query_str(str_buf, sizeof(str_buf), system_charset_info);
@@ -2781,8 +2800,8 @@ static Exit_status check_master_version()
query_str.append(STRING_WITH_LEN("SET @slave_connect_state='"),
system_charset_info);
- size_t n_start_gtids= domain_gtid_filter->get_num_start_gtids();
- rpl_gtid *start_gtids= domain_gtid_filter->get_start_gtids();
+ size_t n_start_gtids= domain_window_gtid_filter->get_num_start_gtids();
+ rpl_gtid *start_gtids= domain_window_gtid_filter->get_start_gtids();
for (size_t gtid_idx = 0; gtid_idx < n_start_gtids; gtid_idx++)
{
@@ -3743,8 +3762,8 @@ int main(int argc, char** argv)
free_tmpdir(&tmpdir);
if (result_file && result_file != stdout)
my_fclose(result_file, MYF(0));
- if (domain_gtid_filter)
- domain_gtid_filter->write_warnings(stderr);
+ if (gtid_event_filter)
+ gtid_event_filter->write_warnings(stderr);
cleanup();
/* We cannot free DBUG, it is used in global destructors after exit(). */
my_end(my_end_arg | MY_DONT_FREE_DBUG);
diff --git a/mysql-test/suite/binlog/t/binlog_mysqlbinlog_gtid_ignore.test b/mysql-test/suite/binlog/t/binlog_mysqlbinlog_gtid_ignore.test
index 93a1b370e46..ffc3ba679ea 100644
--- a/mysql-test/suite/binlog/t/binlog_mysqlbinlog_gtid_ignore.test
+++ b/mysql-test/suite/binlog/t/binlog_mysqlbinlog_gtid_ignore.test
@@ -37,56 +37,59 @@
--echo # Test Setup
--echo ###############################
-## Fix timestamp to avoid varying results.
-#
+# Fix timestamp to avoid varying results.
SET timestamp=1000000000;
RESET MASTER;
-## Save old state
-#
+# Save old state
let $ORIG_GTID_DOMAIN_ID = `select @@session.gtid_domain_id`;
let $ORIG_SERVER_ID = `select @@session.server_id`;
-## Configure test variables
-#
+# Configure test variables
--let $MYSQLD_DATADIR=`select @@datadir`
---let OUT_FILE=$MYSQLTEST_VARDIR/tmp/binlog.out
---let SEARCH_OUTPUT=matches
---let SEARCH_FILE=$OUT_FILE
--let BINLOG_FILENAME= query_get_value(SHOW MASTER STATUS, File, 1)
--let BINLOG_FILE_PARAM= $MYSQLD_DATADIR/$BINLOG_FILENAME.orig
-## Initialize test data
-#
+--let table_inconsistent_err= "table data is inconsistent after replaying binlog events";
+--let table_exists_error= "table exists but binlog playback should have excluded its creation";
+
+# Initialize test data
SET @@session.gtid_domain_id= 0;
SET @@session.server_id= 1;
CREATE TABLE t1 (a int);
-INSERT INTO t1 values (1);
---let t1_checksum= `CHECKSUM TABLE t1`
SET @@session.server_id= 2;
CREATE TABLE t2 (a int);
-INSERT INTO t2 values (2);
+INSERT INTO t2 values (3);
--let t2_checksum= `CHECKSUM TABLE t2`
SET @@session.gtid_domain_id= 1;
SET @@session.server_id= 1;
CREATE TABLE t3 (a int);
-INSERT INTO t3 values (3);
+INSERT INTO t3 values (4);
--let t3_checksum= `CHECKSUM TABLE t3`
-SET @@session.gtid_domain_id= 1;
SET @@session.server_id= 3;
CREATE TABLE t4 (a int);
-INSERT INTO t4 values (4);
+INSERT INTO t4 values (5);
--let t4_checksum= `CHECKSUM TABLE t4`
+SET @@session.gtid_domain_id= 0;
+SET @@session.server_id= 1;
+INSERT INTO t1 values (1);
+--let t1_partial_checksum= `CHECKSUM TABLE t1`
+
SET @@session.gtid_domain_id= 2;
SET @@session.server_id= 1;
CREATE TABLE t5 (a int);
-INSERT INTO t5 values (5);
+INSERT INTO t5 values (6);
--let t5_checksum= `CHECKSUM TABLE t5`
+SET @@session.gtid_domain_id= 0;
+SET @@session.server_id= 1;
+INSERT INTO t1 values (2);
+--let t1_checksum= `CHECKSUM TABLE t1`
+
FLUSH LOGS;
@@ -110,103 +113,308 @@ RESET MASTER;
--exec $MYSQL_BINLOG $BINLOG_FILE_PARAM --ignore-domain-ids=0,1 | $MYSQL
if ($t5_checksum != `CHECKSUM TABLE t5`)
{
- die "Dead";
+ die $table_inconsistent_err;
}
if (`SELECT COUNT(*) FROM information_schema.tables WHERE table_schema = 'test' AND table_name = 't1'`)
{
- die "t1 should not exist as binlog replay should exclude domains 0 and 1 from results";
+ die $table_exists_error;
}
if (`SELECT COUNT(*) FROM information_schema.tables WHERE table_schema = 'test' AND table_name = 't2'`)
{
- die "t2 should not exist as binlog replay should exclude domains 0 and 1 from results";
+ die $table_exists_error;
}
if (`SELECT COUNT(*) FROM information_schema.tables WHERE table_schema = 'test' AND table_name = 't3'`)
{
- die "t3 should not exist as binlog replay should exclude domains 0 and 1 from results";
+ die $table_exists_error;
}
if (`SELECT COUNT(*) FROM information_schema.tables WHERE table_schema = 'test' AND table_name = 't4'`)
{
- die "t4 should not exist as binlog replay should exclude domains 0 and 1 from results";
+ die $table_exists_error;
}
+DROP TABLE t5;
-SELECT COUNT(*) FROM information_schema.tables WHERE table_schema = 'test' AND table_name = 't4';
+--echo #
+--echo # Test Case 2:
+--echo # --do-domain-ids standalone
+--echo # MYSQL_BINLOG BINLOG_FILE_PARAM --do-domain-ids=0,2 | MYSQL
+--exec $MYSQL_BINLOG $BINLOG_FILE_PARAM --do-domain-ids=0,2 | $MYSQL
+if ($t1_checksum != `CHECKSUM TABLE t1`)
+{
+ die $table_inconsistent_err;
+}
+if ($t2_checksum != `CHECKSUM TABLE t2`)
+{
+ die $table_inconsistent_err;
+}
+if ($t5_checksum != `CHECKSUM TABLE t5`)
+{
+ die $table_inconsistent_err;
+}
+if (`SELECT COUNT(*) FROM information_schema.tables WHERE table_schema = 'test' AND table_name = 't3'`)
+{
+ die $table_exists_error;
+}
+if (`SELECT COUNT(*) FROM information_schema.tables WHERE table_schema = 'test' AND table_name = 't4'`)
+{
+ die $table_exists_error;
+}
+DROP TABLE t1;
+DROP TABLE t2;
+DROP TABLE t5;
-#--echo #
-#--echo # Test Case 2:
-#--echo # --do-domain-ids standalone
-#--echo # MYSQL_BINLOG MYSQLD_DATADIR/master-bin.000001 --do-domain-ids=2 > OUT_FILE
-#--exec $MYSQL_BINLOG $MYSQLD_DATADIR/master-bin.000001 --do-domain-ids=2 > $OUT_FILE
-#
-#--echo #
-#--echo # Test Case 3:
-#--echo # --ignore-server-ids standalone
-#--echo # MYSQL_BINLOG MYSQLD_DATADIR/master-bin.000001 --ignore-server-ids=1,3 --base64-output=NEVER > OUT_FILE
-#--exec $MYSQL_BINLOG $MYSQLD_DATADIR/master-bin.000001 --ignore-server-ids=1,3 --base64-output=NEVER > $OUT_FILE
-#--let SEARCH_PATTERN=end_log_pos[^\n]+
-#--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
-#--replace_regex /SQL_LOAD_MB-[0-9]-[0-9]/SQL_LOAD_MB-#-#/ /exec_time=[0-9]*/exec_time=#/ /end_log_pos [0-9]*/end_log_pos #/ /# at [0-9]*/# at #/ /Xid = [0-9]*/Xid = #/ /xid=[0-9]*/xid=#/ /thread_id=[0-9]*/thread_id=#/ /table id [0-9]*/table id #/ /mapped to number [0-9]*/mapped to number #/ /server v [^ ]*/server v #.##.##/ /CRC32 0x[0-9a-f]*/CRC32 XXX/ /collation_server=[0-9]+/collation_server=X/ /character_set_client=[0-9]+/character_set_client=X/ /collation_connection=[0-9]+/collation_connection=X/
-#--source include/search_pattern_in_file.inc
-#
-#--echo #
-#--echo # Test Case 4:
-#--echo # --do-server-ids standalone
-#--echo # MYSQL_BINLOG MYSQLD_DATADIR/master-bin.000001 --do-server-ids=1 --base64-output=NEVER > OUT_FILE
-#--exec $MYSQL_BINLOG $MYSQLD_DATADIR/master-bin.000001 --do-server-ids=1 --base64-output=NEVER > $OUT_FILE
-#--let SEARCH_PATTERN=end_log_pos[^\n]+
-#--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
-#--replace_regex /SQL_LOAD_MB-[0-9]-[0-9]/SQL_LOAD_MB-#-#/ /exec_time=[0-9]*/exec_time=#/ /end_log_pos [0-9]*/end_log_pos #/ /# at [0-9]*/# at #/ /Xid = [0-9]*/Xid = #/ /xid=[0-9]*/xid=#/ /thread_id=[0-9]*/thread_id=#/ /table id [0-9]*/table id #/ /mapped to number [0-9]*/mapped to number #/ /server v [^ ]*/server v #.##.##/ /CRC32 0x[0-9a-f]*/CRC32 XXX/ /collation_server=[0-9]+/collation_server=X/ /character_set_client=[0-9]+/character_set_client=X/ /collation_connection=[0-9]+/collation_connection=X/
-#--source include/search_pattern_in_file.inc
-#
-#--echo #
-#--echo # Test Case 5:
-#--echo # --ignore-domain-ids with --ignore-server-ids intersects the datasets
-#--echo # MYSQL_BINLOG MYSQLD_DATADIR/master-bin.000001 --ignore-server-ids=1,3 --ignore-domain-ids=1,2 --base64-output=NEVER > OUT_FILE
-#--exec $MYSQL_BINLOG $MYSQLD_DATADIR/master-bin.000001 --ignore-server-ids=1,3 --ignore-domain-ids=1,2 --base64-output=NEVER > $OUT_FILE
-#--let SEARCH_PATTERN=end_log_pos[^\n]+
-#--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
-#--replace_regex /SQL_LOAD_MB-[0-9]-[0-9]/SQL_LOAD_MB-#-#/ /exec_time=[0-9]*/exec_time=#/ /end_log_pos [0-9]*/end_log_pos #/ /# at [0-9]*/# at #/ /Xid = [0-9]*/Xid = #/ /xid=[0-9]*/xid=#/ /thread_id=[0-9]*/thread_id=#/ /table id [0-9]*/table id #/ /mapped to number [0-9]*/mapped to number #/ /server v [^ ]*/server v #.##.##/ /CRC32 0x[0-9a-f]*/CRC32 XXX/ /collation_server=[0-9]+/collation_server=X/ /character_set_client=[0-9]+/character_set_client=X/ /collation_connection=[0-9]+/collation_connection=X/
-#--source include/search_pattern_in_file.inc
-#
-#--echo #
-#--echo # Test Case 6:
-#--echo # --ignore-domain-ids with GTID range unions the datasets
-#--echo # MYSQL_BINLOG MYSQLD_DATADIR/master-bin.000001 --do-domain-ids=2 --start-position=1-1-1 --stop-position=1-2-2 --base64-output=NEVER > OUT_FILE
-#--exec $MYSQL_BINLOG $MYSQLD_DATADIR/master-bin.000001 --do-domain-ids=2 --start-position=1-1-1 --stop-position=1-2-2 --base64-output=NEVER > $OUT_FILE
-#--let SEARCH_PATTERN=end_log_pos[^\n]+
-#--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
-#--replace_regex /SQL_LOAD_MB-[0-9]-[0-9]/SQL_LOAD_MB-#-#/ /exec_time=[0-9]*/exec_time=#/ /end_log_pos [0-9]*/end_log_pos #/ /# at [0-9]*/# at #/ /Xid = [0-9]*/Xid = #/ /xid=[0-9]*/xid=#/ /thread_id=[0-9]*/thread_id=#/ /table id [0-9]*/table id #/ /mapped to number [0-9]*/mapped to number #/ /server v [^ ]*/server v #.##.##/ /CRC32 0x[0-9a-f]*/CRC32 XXX/ /collation_server=[0-9]+/collation_server=X/ /character_set_client=[0-9]+/character_set_client=X/ /collation_connection=[0-9]+/collation_connection=X/
-#--source include/search_pattern_in_file.inc
-#
-#--echo #
-#--echo # Test Case 7:
-#--echo # --ignore-server-ids with GTID range intersects the datasets
-#--echo # MYSQL_BINLOG MYSQLD_DATADIR/master-bin.000001 --ignore-server-ids=2 --stop-position=1-3-3 --base64-output=NEVER > OUT_FILE
-#--exec $MYSQL_BINLOG $MYSQLD_DATADIR/master-bin.000001 --ignore-server-ids=2 --stop-position=1-3-3 --base64-output=NEVER > $OUT_FILE
-#--let SEARCH_PATTERN=end_log_pos[^\n]+
-#--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
-#--replace_regex /SQL_LOAD_MB-[0-9]-[0-9]/SQL_LOAD_MB-#-#/ /exec_time=[0-9]*/exec_time=#/ /end_log_pos [0-9]*/end_log_pos #/ /# at [0-9]*/# at #/ /Xid = [0-9]*/Xid = #/ /xid=[0-9]*/xid=#/ /thread_id=[0-9]*/thread_id=#/ /table id [0-9]*/table id #/ /mapped to number [0-9]*/mapped to number #/ /server v [^ ]*/server v #.##.##/ /CRC32 0x[0-9a-f]*/CRC32 XXX/ /collation_server=[0-9]+/collation_server=X/ /character_set_client=[0-9]+/character_set_client=X/ /collation_connection=[0-9]+/collation_connection=X/
-#--source include/search_pattern_in_file.inc
-#
-#--echo #
-#--echo # Test Case 8:
-#--echo # --ignore-domain-ids, --ignore-server-ids, and GTID range
-#--echo # MYSQL_BINLOG MYSQLD_DATADIR/master-bin.000001 --do-domain-ids=0 --ignore-server-ids=2 --stop-position=1-3-3 --base64-output=NEVER > OUT_FILE
-#--exec $MYSQL_BINLOG $MYSQLD_DATADIR/master-bin.000001 --do-domain-ids=0 --ignore-server-ids=2 --stop-position=1-3-3 --base64-output=NEVER > $OUT_FILE
-#--let SEARCH_PATTERN=end_log_pos[^\n]+
-#--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
-#--replace_regex /SQL_LOAD_MB-[0-9]-[0-9]/SQL_LOAD_MB-#-#/ /exec_time=[0-9]*/exec_time=#/ /end_log_pos [0-9]*/end_log_pos #/ /# at [0-9]*/# at #/ /Xid = [0-9]*/Xid = #/ /xid=[0-9]*/xid=#/ /thread_id=[0-9]*/thread_id=#/ /table id [0-9]*/table id #/ /mapped to number [0-9]*/mapped to number #/ /server v [^ ]*/server v #.##.##/ /CRC32 0x[0-9a-f]*/CRC32 XXX/ /collation_server=[0-9]+/collation_server=X/ /character_set_client=[0-9]+/character_set_client=X/ /collation_connection=[0-9]+/collation_connection=X/
-#--source include/search_pattern_in_file.inc
-#
-#--echo #
-#--echo # Test Case 9:
-#--echo # --server-id and --do-server-ids union results together
-#--echo # MYSQL_BINLOG MYSQLD_DATADIR/master-bin.000001 --do-server-ids=1,2 --server-id=1 --base64-output=NEVER > OUT_FILE
-#--exec $MYSQL_BINLOG $MYSQLD_DATADIR/master-bin.000001 --do-server-ids=1,2 --server-id=1 --base64-output=NEVER > $OUT_FILE
-#--let SEARCH_PATTERN=end_log_pos[^\n]+
-#--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
-#--replace_regex /SQL_LOAD_MB-[0-9]-[0-9]/SQL_LOAD_MB-#-#/ /exec_time=[0-9]*/exec_time=#/ /end_log_pos [0-9]*/end_log_pos #/ /# at [0-9]*/# at #/ /Xid = [0-9]*/Xid = #/ /xid=[0-9]*/xid=#/ /thread_id=[0-9]*/thread_id=#/ /table id [0-9]*/table id #/ /mapped to number [0-9]*/mapped to number #/ /server v [^ ]*/server v #.##.##/ /CRC32 0x[0-9a-f]*/CRC32 XXX/ /collation_server=[0-9]+/collation_server=X/ /character_set_client=[0-9]+/character_set_client=X/ /collation_connection=[0-9]+/collation_connection=X/
-#--source include/search_pattern_in_file.inc
+--echo #
+--echo # Test Case 3:
+--echo # --ignore-server-ids standalone
+--echo # MYSQL_BINLOG BINLOG_FILE_PARAM --ignore-server-ids=2,3 | MYSQL
+--exec $MYSQL_BINLOG $BINLOG_FILE_PARAM --ignore-server-ids=2,3 | $MYSQL
+if ($t1_checksum != `CHECKSUM TABLE t1`)
+{
+ die $table_inconsistent_err;
+}
+if ($t3_checksum != `CHECKSUM TABLE t3`)
+{
+ die $table_inconsistent_err;
+}
+if ($t5_checksum != `CHECKSUM TABLE t5`)
+{
+ die $table_inconsistent_err;
+}
+if (`SELECT COUNT(*) FROM information_schema.tables WHERE table_schema = 'test' AND table_name = 't2'`)
+{
+ die $table_exists_error;
+}
+if (`SELECT COUNT(*) FROM information_schema.tables WHERE table_schema = 'test' AND table_name = 't4'`)
+{
+ die $table_exists_error;
+}
+DROP TABLE t1;
+DROP TABLE t3;
+DROP TABLE t5;
+--echo #
+--echo # Test Case 4:
+--echo # --do-server-ids standalone
+--echo # MYSQL_BINLOG BINLOG_FILE_PARAM --do-server-ids=2,3 | MYSQL
+--exec $MYSQL_BINLOG $BINLOG_FILE_PARAM --do-server-ids=2,3 | $MYSQL
+if ($t2_checksum != `CHECKSUM TABLE t2`)
+{
+ die $table_inconsistent_err;
+}
+if ($t4_checksum != `CHECKSUM TABLE t4`)
+{
+ die $table_inconsistent_err;
+}
+if (`SELECT COUNT(*) FROM information_schema.tables WHERE table_schema = 'test' AND table_name = 't1'`)
+{
+ die $table_exists_error;
+}
+if (`SELECT COUNT(*) FROM information_schema.tables WHERE table_schema = 'test' AND table_name = 't3'`)
+{
+ die $table_exists_error;
+}
+if (`SELECT COUNT(*) FROM information_schema.tables WHERE table_schema = 'test' AND table_name = 't5'`)
+{
+ die $table_exists_error;
+}
+DROP TABLE t2;
+DROP TABLE t4;
+
+--echo #
+--echo # Test Case 5:
+--echo # --ignore-domain-ids with --ignore-server-ids intersects the datasets
+--echo # MYSQL_BINLOG BINLOG_FILE_PARAM --ignore-server-ids=1,3 --ignore-domain-ids=1,2 | MYSQL
+--exec $MYSQL_BINLOG $BINLOG_FILE_PARAM --ignore-server-ids=1,3 --ignore-domain-ids=1,2 | $MYSQL
+if ($t2_checksum != `CHECKSUM TABLE t2`)
+{
+ die $table_inconsistent_err;
+}
+if (`SELECT COUNT(*) FROM information_schema.tables WHERE table_schema = 'test' AND table_name = 't1'`)
+{
+ die $table_exists_error;
+}
+if (`SELECT COUNT(*) FROM information_schema.tables WHERE table_schema = 'test' AND table_name = 't3'`)
+{
+ die $table_exists_error;
+}
+if (`SELECT COUNT(*) FROM information_schema.tables WHERE table_schema = 'test' AND table_name = 't4'`)
+{
+ die $table_exists_error;
+}
+if (`SELECT COUNT(*) FROM information_schema.tables WHERE table_schema = 'test' AND table_name = 't5'`)
+{
+ die $table_exists_error;
+}
+DROP TABLE t2;
+
+
+--echo #
+--echo # Test Case 6:
+--echo # --do-domain-ids with GTID range intersects the datasets
+--echo # MYSQL_BINLOG BINLOG_FILE_PARAM --do-domain-ids=0 --start-position=0-1-0 --stop-position=0-1-4 | MYSQL
+--exec $MYSQL_BINLOG $BINLOG_FILE_PARAM --do-domain-ids=0 --start-position=0-1-0 --stop-position=0-1-4 | $MYSQL
+if ($t1_partial_checksum != `CHECKSUM TABLE t1`)
+{
+ die $table_inconsistent_err;
+}
+if ($t2_checksum != `CHECKSUM TABLE t2`)
+{
+ die $table_inconsistent_err;
+}
+if (`SELECT COUNT(*) FROM information_schema.tables WHERE table_schema = 'test' AND table_name = 't3'`)
+{
+ die $table_exists_error;
+}
+if (`SELECT COUNT(*) FROM information_schema.tables WHERE table_schema = 'test' AND table_name = 't4'`)
+{
+ die $table_exists_error;
+}
+if (`SELECT COUNT(*) FROM information_schema.tables WHERE table_schema = 'test' AND table_name = 't5'`)
+{
+ die $table_exists_error;
+}
+DROP TABLE t1;
+DROP TABLE t2;
+
+--echo #
+--echo # Test Case 7:
+--echo # --ignore-server-ids with GTID range intersects the datasets
+--echo # MYSQL_BINLOG BINLOG_FILE_PARAM --ignore-server-ids=2,3 --start-position=0-1-0 --stop-position=0-1-4 | MYSQL
+--exec $MYSQL_BINLOG $BINLOG_FILE_PARAM --ignore-server-ids=2,3 --start-position=0-1-0 --stop-position=0-1-4
+--exec $MYSQL_BINLOG $BINLOG_FILE_PARAM --ignore-server-ids=2,3 --start-position=0-1-0 --stop-position=0-1-4 | $MYSQL
+if ($t1_partial_checksum != `CHECKSUM TABLE t1`)
+{
+ die $table_inconsistent_err;
+}
+if ($t3_checksum != `CHECKSUM TABLE t3`)
+{
+ die $table_inconsistent_err;
+}
+if (`SELECT COUNT(*) FROM information_schema.tables WHERE table_schema = 'test' AND table_name = 't2'`)
+{
+ die $table_exists_error;
+}
+if (`SELECT COUNT(*) FROM information_schema.tables WHERE table_schema = 'test' AND table_name = 't4'`)
+{
+ die $table_exists_error;
+}
+if (`SELECT COUNT(*) FROM information_schema.tables WHERE table_schema = 'test' AND table_name = 't5'`)
+{
+ die $table_exists_error;
+}
+DROP TABLE t1;
+DROP TABLE t3;
+
+
+--echo #
+--echo # Test Case 8:
+--echo # --ignore-domain-ids, --ignore-server-ids, and GTID range
+--echo # MYSQL_BINLOG BINLOG_FILE_PARAM --ignore-domain-ids=0 --ignore-server-ids=2,3 --stop-position=0-1-4 | MYSQL
+--exec $MYSQL_BINLOG $BINLOG_FILE_PARAM --ignore-domain-ids=0 --ignore-server-ids=2,3 --stop-position=0-1-4 | $MYSQL
+if ($t3_checksum != `CHECKSUM TABLE t3`)
+{
+ die $table_inconsistent_err;
+}
+if (`SELECT COUNT(*) FROM information_schema.tables WHERE table_schema = 'test' AND table_name = 't1'`)
+{
+ die $table_exists_error;
+}
+if (`SELECT COUNT(*) FROM information_schema.tables WHERE table_schema = 'test' AND table_name = 't2'`)
+{
+ die $table_exists_error;
+}
+if (`SELECT COUNT(*) FROM information_schema.tables WHERE table_schema = 'test' AND table_name = 't4'`)
+{
+ die $table_exists_error;
+}
+if (`SELECT COUNT(*) FROM information_schema.tables WHERE table_schema = 'test' AND table_name = 't5'`)
+{
+ die $table_exists_error;
+}
+DROP TABLE t3;
+
+--echo #
+--echo # Test Case 9:
+--echo # If the same domain id rule is specified multiple times, only the values
+--echo # from the last specification will be used
+--echo # MYSQL_BINLOG BINLOG_FILE_PARAM --do-domain-ids=0,1 --do-domain-ids=2 | MYSQL
+--exec $MYSQL_BINLOG $BINLOG_FILE_PARAM --do-domain-ids=0,1 --do-domain-ids=2 | $MYSQL
+if ($t5_checksum != `CHECKSUM TABLE t5`)
+{
+ die $table_inconsistent_err;
+}
+if (`SELECT COUNT(*) FROM information_schema.tables WHERE table_schema = 'test' AND table_name = 't1'`)
+{
+ die $table_exists_error;
+}
+if (`SELECT COUNT(*) FROM information_schema.tables WHERE table_schema = 'test' AND table_name = 't2'`)
+{
+ die $table_exists_error;
+}
+if (`SELECT COUNT(*) FROM information_schema.tables WHERE table_schema = 'test' AND table_name = 't3'`)
+{
+ die $table_exists_error;
+}
+if (`SELECT COUNT(*) FROM information_schema.tables WHERE table_schema = 'test' AND table_name = 't4'`)
+{
+ die $table_exists_error;
+}
+DROP TABLE t5;
+
+--echo #
+--echo # Test Case 10:
+--echo # --server-id and --do-server-ids are aliases and the latter will
+--echo # override the former
+--echo # MYSQL_BINLOG BINLOG_FILE_PARAM --do-server-ids=1,2 --server-id=3 | MYSQL
+--exec $MYSQL_BINLOG $BINLOG_FILE_PARAM --do-server-ids=1,2 --server-id=3 | $MYSQL
+if ($t4_checksum != `CHECKSUM TABLE t4`)
+{
+ die $table_inconsistent_err;
+}
+if (`SELECT COUNT(*) FROM information_schema.tables WHERE table_schema = 'test' AND table_name = 't1'`)
+{
+ die $table_exists_error;
+}
+if (`SELECT COUNT(*) FROM information_schema.tables WHERE table_schema = 'test' AND table_name = 't2'`)
+{
+ die $table_exists_error;
+}
+if (`SELECT COUNT(*) FROM information_schema.tables WHERE table_schema = 'test' AND table_name = 't3'`)
+{
+ die $table_exists_error;
+}
+if (`SELECT COUNT(*) FROM information_schema.tables WHERE table_schema = 'test' AND table_name = 't5'`)
+{
+ die $table_exists_error;
+}
+DROP TABLE t4;
+
+--echo #
+--echo # Test Case 11:
+--echo # --ignore-domain-ids, --ignore-server-ids, and multiple GTID ranges
+--echo # MYSQL_BINLOG BINLOG_FILE_PARAM --ignore-domain-ids=0 --ignore-server-ids=2,3 --start-position=0-1-0,1-1-0 --stop-position=1-1-2,0-1-4| MYSQL
+--exec $MYSQL_BINLOG $BINLOG_FILE_PARAM --ignore-domain-ids=0 --ignore-server-ids=2,3 --start-position=0-1-0,1-1-0 --stop-position=1-1-2,0-1-4
+--exec $MYSQL_BINLOG $BINLOG_FILE_PARAM --ignore-domain-ids=0 --ignore-server-ids=2,3 --start-position=0-1-0,1-1-0 --stop-position=1-1-2,0-1-4 | $MYSQL
+if ($t3_checksum != `CHECKSUM TABLE t3`)
+{
+ die $table_inconsistent_err;
+}
+if (`SELECT COUNT(*) FROM information_schema.tables WHERE table_schema = 'test' AND table_name = 't1'`)
+{
+ die $table_exists_error;
+}
+if (`SELECT COUNT(*) FROM information_schema.tables WHERE table_schema = 'test' AND table_name = 't2'`)
+{
+ die $table_exists_error;
+}
+if (`SELECT COUNT(*) FROM information_schema.tables WHERE table_schema = 'test' AND table_name = 't4'`)
+{
+ die $table_exists_error;
+}
+if (`SELECT COUNT(*) FROM information_schema.tables WHERE table_schema = 'test' AND table_name = 't5'`)
+{
+ die $table_exists_error;
+}
+DROP TABLE t3;
--echo ##############################
--echo # Error Cases
@@ -215,23 +423,23 @@ SELECT COUNT(*) FROM information_schema.tables WHERE table_schema = 'test' AND t
--echo #
--echo # Error Case 1:
--echo # --ignore-domain-ids and --do-domain-ids both specified
---echo # MYSQL_BINLOG MYSQLD_DATADIR/master-bin.000001 --ignore-domain-ids=0 --do-domain-ids=1 --base64-output=NEVER > OUT_FILE
+--echo # MYSQL_BINLOG BINLOG_FILE_PARAM --ignore-domain-ids=0 --do-domain-ids=1
--error 1
---exec $MYSQL_BINLOG $MYSQLD_DATADIR/master-bin.000001 --ignore-domain-ids=0 --do-domain-ids=1 --base64-output=NEVER > $OUT_FILE
+--exec $MYSQL_BINLOG $BINLOG_FILE_PARAM --ignore-domain-ids=0 --do-domain-ids=1
--echo #
--echo # Error Case 2:
--echo # --ignore-server-ids and --do-server-ids both specified
---echo # MYSQL_BINLOG MYSQLD_DATADIR/master-bin.000001 --ignore-server-ids=1 --do-server-ids=2 --base64-output=NEVER > OUT_FILE
+--echo # MYSQL_BINLOG BINLOG_FILE_PARAM --do-server-ids=1 --ignore-server-ids=2
--error 1
---exec $MYSQL_BINLOG $MYSQLD_DATADIR/master-bin.000001 --ignore-server-ids=1 --do-server-ids=2 --base64-output=NEVER > $OUT_FILE
+--exec $MYSQL_BINLOG $BINLOG_FILE_PARAM --do-server-ids=1 --ignore-server-ids=2
--echo #
--echo # Error Case 3:
---echo # --(ignore|do)-domain-ids and GTID range specified on the same domain
---echo # MYSQL_BINLOG MYSQLD_DATADIR/master-bin.000001 --start-position=0-1-1 --ignore-domain-ids=0 --base64-output=NEVER > OUT_FILE
+--echo # Invalid ID number provided
+--echo # MYSQL_BINLOG BINLOG_FILE_PARAM --ignore-server-ids=-1
--error 1
---exec $MYSQL_BINLOG $MYSQLD_DATADIR/master-bin.000001 --start-position=0-1-1 --ignore-domain-ids=0 --base64-output=NEVER > $OUT_FILE
+--exec $MYSQL_BINLOG $BINLOG_FILE_PARAM --ignore-server-ids=-1
--echo ##############################
--echo # Cleanup
diff --git a/sql/rpl_gtid.cc b/sql/rpl_gtid.cc
index d19628a0395..2936839643a 100644
--- a/sql/rpl_gtid.cc
+++ b/sql/rpl_gtid.cc
@@ -3340,13 +3340,21 @@ int Id_delegating_gtid_event_filter::set_blacklist(
if (m_whitelist_set)
{
/*
- Whitelist is already set, we can't do a blacklist and whitelist
- together.
+ Whitelist is already set, we can't do a blacklist and whitelist together
*/
err= 1;
+ sql_print_error("Cannot create exclusion rule for %s ids because an "
+ "inclusion rule already exists (possibly from specifying "
+ "both --do-%s-ids and --ignore-%s-ids)",
+ get_id_type_name(), get_id_type_name(),
+ get_id_type_name());
goto err;
}
+ /* If a blacklist is specified more than once, only use the latest values */
+ if (m_blacklist_set)
+ my_hash_reset(&m_filters_by_id_hash);
+
for (id_ctr= 0; id_ctr < n_ids; id_ctr++)
{
gtid_filter_identifier filter_id= id_list[id_ctr];
@@ -3362,10 +3370,6 @@ int Id_delegating_gtid_event_filter::set_blacklist(
{
map_element->filter= new Reject_all_gtid_filter();
m_num_explicit_filters++;
- //Identifiable_gtid_event_filter *rejecting_filter=
- // new Identifiable_gtid_event_filter(filter_id,
- // new Reject_all_gtid_filter());
- //map_element->filter= rejecting_filter;
}
else if (map_element->filter->get_filter_type() !=
REJECT_ALL_GTID_FILTER_TYPE)
@@ -3375,6 +3379,9 @@ int Id_delegating_gtid_event_filter::set_blacklist(
Error.
*/
err= 1;
+ sql_print_error("Cannot set filter blacklist on %s id %lu because it "
+ "already has a filtering rule",
+ get_id_type_name(), filter_id);
goto err;
}
}
@@ -3400,13 +3407,21 @@ int Id_delegating_gtid_event_filter::set_whitelist(
if (m_blacklist_set)
{
/*
- Blacklist is already set, we can't do a blacklist and whitelist
- together.
+ Blacklist is already set, we can't do a blacklist and whitelist together
*/
err= 1;
+ sql_print_error("Cannot create inclusion rule for %s ids because an "
+ "exclusion rule already exists (possibly from specifying "
+ "both --ignore-%s-ids and --do-%s-ids)",
+ get_id_type_name(), get_id_type_name(),
+ get_id_type_name());
goto err;
}
+ /* If a whitelist is specified more than once, only use the latest values */
+ if (m_whitelist_set)
+ my_hash_reset(&m_filters_by_id_hash);
+
for (id_ctr= 0; id_ctr < n_ids; id_ctr++)
{
gtid_filter_identifier filter_id= id_list[id_ctr];
@@ -3422,10 +3437,6 @@ int Id_delegating_gtid_event_filter::set_whitelist(
{
map_element->filter= new Accept_all_gtid_filter();
m_num_explicit_filters++;
- //Identifiable_gtid_event_filter *accepting_filter=
- // new Identifiable_gtid_event_filter(filter_id,
- // new Accept_all_gtid_filter());
- //map_element->filter= accepting_filter;
}
else if (map_element->filter->get_filter_type() !=
ACCEPT_ALL_GTID_FILTER_TYPE)
@@ -3435,6 +3446,9 @@ int Id_delegating_gtid_event_filter::set_whitelist(
Error.
*/
err= 1;
+ sql_print_error("Cannot set filter whitelist on %s id %lu because it "
+ "already has a filtering rule",
+ get_id_type_name(), filter_id);
goto err;
}
}
diff --git a/sql/rpl_gtid.h b/sql/rpl_gtid.h
index 8eba3c549a5..7586d29c0ef 100644
--- a/sql/rpl_gtid.h
+++ b/sql/rpl_gtid.h
@@ -632,6 +632,7 @@ public:
uint32 get_filter_type() { return DELEGATING_GTID_FILTER_TYPE; }
virtual gtid_filter_identifier get_id_from_gtid(rpl_gtid *) = 0;
+ virtual const char* get_id_type_name() = 0;
/*
Set the default behavior to include all ids except for the ones that are
@@ -701,6 +702,8 @@ public:
return gtid->domain_id;
}
+ const char* get_id_type_name() { return "domain"; }
+
/*
Helper function to start a GTID window filter at the given GTID
@@ -769,6 +772,7 @@ private:
*/
class Server_gtid_event_filter : public Id_delegating_gtid_event_filter
{
+
public:
/*
Returns the server id of from the input GTID
@@ -777,6 +781,8 @@ public:
{
return gtid->server_id;
}
+
+ const char* get_id_type_name() { return "server"; }
};
/*
@@ -805,10 +811,15 @@ public:
Gtid_event_filter *get_filter_1() { return m_filter1; }
Gtid_event_filter *get_filter_2() { return m_filter2; }
+ /*
+ Returns true if either filter has finished. To elaborate, as this filter
+ performs an intersection, if either filter has finished, the result would
+ be excluded regardless.
+ */
my_bool has_finished()
{
DBUG_ASSERT(m_filter1 && m_filter2);
- return m_filter1->has_finished() && m_filter2->has_finished();
+ return m_filter1->has_finished() || m_filter2->has_finished();
}
void write_warnings(FILE *out)