summaryrefslogtreecommitdiff
path: root/sql/rpl_gtid.cc
diff options
context:
space:
mode:
Diffstat (limited to 'sql/rpl_gtid.cc')
-rw-r--r--sql/rpl_gtid.cc143
1 files changed, 142 insertions, 1 deletions
diff --git a/sql/rpl_gtid.cc b/sql/rpl_gtid.cc
index a7f8298506f..367c8b7a8c5 100644
--- a/sql/rpl_gtid.cc
+++ b/sql/rpl_gtid.cc
@@ -3308,7 +3308,8 @@ void free_gtid_filter_element(void *p)
}
Id_delegating_gtid_event_filter::Id_delegating_gtid_event_filter()
- : m_num_explicit_filters(0), m_num_completed_filters(0)
+ : m_num_explicit_filters(0), m_num_completed_filters(0),
+ m_whitelist_set(FALSE), m_blacklist_set(FALSE)
{
my_hash_init(PSI_INSTRUMENT_ME, &m_filters_by_id_hash, &my_charset_bin, 32,
offsetof(gtid_filter_element, identifier),
@@ -3392,6 +3393,140 @@ my_bool Id_delegating_gtid_event_filter::exclude(rpl_gtid *gtid)
return ret;
}
+int Id_delegating_gtid_event_filter::set_blacklist(
+ gtid_filter_identifier *id_list, size_t n_ids)
+{
+ size_t id_ctr;
+ int err;
+
+ if (m_whitelist_set)
+ {
+ /*
+ 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];
+ gtid_filter_element *map_element=
+ find_or_create_filter_element_for_id(filter_id);
+
+ if(map_element == NULL)
+ {
+ err= 1;
+ goto err;
+ }
+ else if (map_element->filter == NULL)
+ {
+ map_element->filter= new Reject_all_gtid_filter();
+ m_num_explicit_filters++;
+ }
+ else if (map_element->filter->get_filter_type() !=
+ REJECT_ALL_GTID_FILTER_TYPE)
+ {
+ /*
+ There is a different filter placed on an id that should be blacklisted.
+ 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;
+ }
+ }
+
+ /*
+ With a blacklist, we by default want to accept everything that is not
+ specified in the list
+ */
+ set_default_filter(new Accept_all_gtid_filter());
+ m_blacklist_set= TRUE;
+ err= 0;
+
+err:
+ return err;
+}
+
+int Id_delegating_gtid_event_filter::set_whitelist(
+ gtid_filter_identifier *id_list, size_t n_ids)
+{
+ size_t id_ctr;
+ int err;
+
+ if (m_blacklist_set)
+ {
+ /*
+ 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];
+ gtid_filter_element *map_element=
+ find_or_create_filter_element_for_id(filter_id);
+
+ if(map_element == NULL)
+ {
+ err= 1;
+ goto err;
+ }
+ else if (map_element->filter == NULL)
+ {
+ map_element->filter= new Accept_all_gtid_filter();
+ m_num_explicit_filters++;
+ }
+ else if (map_element->filter->get_filter_type() !=
+ ACCEPT_ALL_GTID_FILTER_TYPE)
+ {
+ /*
+ There is a different filter placed on an id that should be whitelisted.
+ 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;
+ }
+ }
+
+ /*
+ With a whitelist, we by only want to accept the ids which are specified.
+ Everything else should be denied.
+ */
+ set_default_filter(new Reject_all_gtid_filter());
+ m_whitelist_set= TRUE;
+ err= 0;
+
+err:
+ return err;
+}
+
Window_gtid_event_filter *
Domain_gtid_event_filter::find_or_create_window_filter_for_id(
uint32 domain_id)
@@ -3608,3 +3743,9 @@ void Domain_gtid_event_filter::clear_stop_gtids()
reset_dynamic(&m_stop_filters);
}
+
+my_bool Intersecting_gtid_event_filter::exclude(rpl_gtid *gtid)
+{
+ DBUG_ASSERT(m_filter1 && m_filter2);
+ return m_filter1->exclude(gtid) || m_filter2->exclude(gtid);
+}