Bug #111914 Global replication filters replace channel specific filters
Submitted: 28 Jul 2023 16:38 Modified: 31 Jul 2023 6:02
Reporter: Chelluru Vidyadhar Email Updates:
Status: Verified Impact on me:
None 
Category:MySQL Server: Replication Severity:S2 (Serious)
Version:8.0.33 OS:Any
Assigned to: CPU Architecture:Any

[28 Jul 2023 16:38] Chelluru Vidyadhar
Description:
While configuring replication filters using "CHANGE REPLICATION FILTER" command, all global replication filters are copied to the channel specific filters by default initially. After a while once can consider to configure channel specific filters. At this stage, global specific filters are not applicable to mentioned channel and only filters defined for particular channel will be applicable. So far it can be considered as expected behavior (documented).

When we change the global filters in later stages, its replacing the channel specific filters. 

How to repeat:

mysql> CHANGE REPLICATION FILTER REPLICATE_IGNORE_DB=(`globaldb`);
Query OK, 0 rows affected (0.00 sec)

mysql> select * from performance_schema.replication_applier_global_filters;
+---------------------+-------------+---------------------------+----------------------------+
| FILTER_NAME         | FILTER_RULE | CONFIGURED_BY             | ACTIVE_SINCE               |
+---------------------+-------------+---------------------------+----------------------------+
| REPLICATE_IGNORE_DB | globaldb    | CHANGE_REPLICATION_FILTER | 2023-07-28 16:17:56.833261 |
+---------------------+-------------+---------------------------+----------------------------+
1 row in set (0.00 sec)

mysql> select * from performance_schema.replication_applier_filters;
+--------------+---------------------+-------------+---------------------------+----------------------------+---------+
| CHANNEL_NAME | FILTER_NAME         | FILTER_RULE | CONFIGURED_BY             | ACTIVE_SINCE               | COUNTER |
+--------------+---------------------+-------------+---------------------------+----------------------------+---------+
|              | REPLICATE_IGNORE_DB | globaldb    | CHANGE_REPLICATION_FILTER | 2023-07-28 16:17:56.833261 |       0 |
+--------------+---------------------+-------------+---------------------------+----------------------------+---------+
1 row in set (0.01 sec)

mysql> CHANGE REPLICATION FILTER REPLICATE_IGNORE_DB=(`channeldb`) for channel '';
Query OK, 0 rows affected (0.00 sec)

mysql> select * from performance_schema.replication_applier_global_filters;
+---------------------+-------------+---------------------------+----------------------------+
| FILTER_NAME         | FILTER_RULE | CONFIGURED_BY             | ACTIVE_SINCE               |
+---------------------+-------------+---------------------------+----------------------------+
| REPLICATE_IGNORE_DB | globaldb    | CHANGE_REPLICATION_FILTER | 2023-07-28 16:17:56.833261 |
+---------------------+-------------+---------------------------+----------------------------+
1 row in set (0.00 sec)

mysql> select * from performance_schema.replication_applier_filters;
+--------------+---------------------+-------------+---------------------------------------+----------------------------+---------+
| CHANNEL_NAME | FILTER_NAME         | FILTER_RULE | CONFIGURED_BY                         | ACTIVE_SINCE               | COUNTER |
+--------------+---------------------+-------------+---------------------------------------+----------------------------+---------+
|              | REPLICATE_IGNORE_DB | channeldb   | CHANGE_REPLICATION_FILTER_FOR_CHANNEL | 2023-07-28 16:19:10.127976 |       0 |
+--------------+---------------------+-------------+---------------------------------------+----------------------------+---------+
1 row in set (0.00 sec)

-- below command replace channel specific filters

mysql> CHANGE REPLICATION FILTER REPLICATE_IGNORE_DB=(`globaldb`,`globaldb123`);
Query OK, 0 rows affected (0.00 sec)

mysql> select * from performance_schema.replication_applier_filters;
+--------------+---------------------+----------------------+---------------------------+----------------------------+---------+
| CHANNEL_NAME | FILTER_NAME         | FILTER_RULE          | CONFIGURED_BY             | ACTIVE_SINCE               | COUNTER |
+--------------+---------------------+----------------------+---------------------------+----------------------------+---------+
|              | REPLICATE_IGNORE_DB | globaldb,globaldb123 | CHANGE_REPLICATION_FILTER | 2023-07-28 16:20:57.524803 |       0 |
+--------------+---------------------+----------------------+---------------------------+----------------------------+---------+
1 row in set (0.00 sec)

mysql> select * from performance_schema.replication_applier_global_filters;
+---------------------+----------------------+---------------------------+----------------------------+
| FILTER_NAME         | FILTER_RULE          | CONFIGURED_BY             | ACTIVE_SINCE               |
+---------------------+----------------------+---------------------------+----------------------------+
| REPLICATE_IGNORE_DB | globaldb,globaldb123 | CHANGE_REPLICATION_FILTER | 2023-07-28 16:20:57.524803 |
+---------------------+----------------------+---------------------------+----------------------------+
1 row in set (0.01 sec)

Suggested fix:
 The global filters should be copied to any channel only if particular channel has no channel specific filters. The channel specific filters should not be replaced with global filter unless channel specific filters are explicitly reset.
[31 Jul 2023 6:02] MySQL Verification Team
Hello Chelluru,

Thank you for the report and feedback.
Verified as described.

regards,
Umesh
[11 Aug 2023 10:26] Sven Sandberg
Posted by developer:
 
It is working this way according to both the original design in WL#7361 and the documentation at https://dev.mysql.com/doc/refman/8.0/en/change-replication-filter.html :

"On a replica with multiple replication channels configured, issuing CHANGE REPLICATION FILTER with no FOR CHANNEL clause configures the replication filter for every configured replication channel, and for the global replication filters. For every filter type, if the filter type is listed in the statement, then any existing filter rules of that type are replaced by the filter rules specified in the most recently issued statement, otherwise the old value of the filter type is retained."

It can be debated if other schemes are more usable or not, but it cannot be changed at this point since it would break compatibility.

You can work around this by recreating the per-channel filters.