本节说明在存在多个复制通道的情况下如何使用复制过滤器,例如在多源复制拓扑中。复制过滤器可以是全局的,也可以是特定于通道的,这使您能够在特定复制通道上配置具有复制过滤器的多源副本。当同一数据库或表存在于多个源上,而副本只需要从一个源复制它时,特定于通道的复制过滤器在多源复制拓扑中特别有用。
有关设置复制通道的说明,请参见 第 19.1.5 节,“MySQL 多源复制”,有关其工作原理的更多信息,请参见 第 19.2.2 节,“复制通道”。
多源副本上的每个通道都必须从不同的源复制。您无法从单个副本设置多个复制通道到单个源,即使您使用复制过滤器在每个通道上选择不同的数据进行复制。这是因为副本的服务器 ID 在复制拓扑中必须是唯一的。源仅通过服务器 ID 区分副本,而不是通过复制通道的名称,因此它无法识别来自同一副本的不同复制通道。
在为组复制配置的 MySQL 服务器实例上,特定于通道的复制过滤器可用于与组复制无关的复制通道,例如组成员也充当外部源的副本时。它们不能用于 group_replication_applier
或 group_replication_recovery
通道。在这些通道上进行过滤会导致组无法就一致状态达成一致。
对于处于菱形拓扑(副本从两个或多个源复制,而这些源又从一个共同的源复制)中的多源副本,当使用基于 GTID 的复制时,请确保多源副本上所有通道的任何复制过滤器或其他通道配置都相同。在基于 GTID 的复制中,过滤器仅应用于事务数据,而 GTID 不会被过滤掉。这样做是为了使副本的 GTID 集与源的 GTID 集保持一致,这意味着可以使用 GTID 自动定位而无需在每次定位时重新获取已过滤掉的事务。在以下情况下,下游副本是多源的,并且从菱形拓扑中的多个源接收到相同的事务,下游副本现在将拥有该事务的多个版本,结果取决于哪个通道首先应用该事务。尝试应用它的第二个通道将使用 GTID 自动跳过跳过该事务,因为该事务的 GTID 已由第一个通道添加到 gtid_executed
集中。如果通道上的过滤相同,则不会出现问题,因为事务的所有版本都包含相同的数据,因此结果相同。但是,如果通道上的过滤不同,数据库可能会变得不一致,并且复制可能会挂起。
当存在多个复制通道时,例如在多源复制拓扑中,复制过滤器将按如下方式应用
任何指定的全局复制过滤器都会添加到过滤器类型的全局复制过滤器中(例如
do_db
、do_ignore_table
等)。任何特定于通道的复制过滤器都会将过滤器添加到指定通道的指定过滤器类型的复制过滤器中。
每个复制通道都会将全局复制过滤器复制到其特定于通道的复制过滤器中,前提是未配置这种类型的特定于通道的复制过滤器。
每个通道都会使用其特定于通道的复制过滤器来过滤复制流。
创建特定于通道的复制过滤器的语法扩展了现有的 SQL 语句和命令选项。如果未指定复制通道,则会配置全局复制过滤器以确保向后兼容性。 CHANGE REPLICATION FILTER
语句支持 FOR CHANNEL
子句来在线配置特定于通道的过滤器。用于配置过滤器的 --replicate-*
命令选项可以使用以下形式指定复制通道: --replicate-
。假设在服务器启动之前存在通道 filter_type
=channel_name
:filter_details
channel_1
和 channel_2
;在这种情况下,使用命令行选项 --replicate-do-db=db1
--replicate-do-db=channel_1:db2
--replicate-do-db=db3
--replicate-ignore-db=db4
--replicate-ignore-db=channel_2:db5
--replicate-wild-do-table=channel_1:db6.t1%
启动副本将导致以下结果:
全局复制过滤器:
do_db=db1,db3
;ignore_db=db4
通道 channel_1 上的特定于通道的过滤器:
do_db=db2
;ignore_db=db4
;wild-do-table=db6.t1%
通道 channel_2 上的特定于通道的过滤器:
do_db=db1,db3
;ignore_db=db5
这些相同的规则可以应用于启动时,在副本的 my.cnf
文件中包含这些规则,如下所示
replicate-do-db=db1
replicate-do-db=channel_1:db2
replicate-ignore-db=db4
replicate-ignore-db=channel_2:db5
replicate-wild-do-table=db6.channel_1.t1%
要监控此类设置中的复制过滤器,请使用 replication_applier_global_filters
和 replication_applier_filters
表。
与复制过滤器相关的命令选项可以采用可选的 channel
,后跟一个冒号,再后跟过滤器规范。第一个冒号被解释为分隔符,后续冒号被解释为文字冒号。以下命令选项支持使用此格式的特定于通道的复制过滤器
--replicate-do-db=
channel
:database_id
--replicate-ignore-db=
channel
:database_id
--replicate-do-table=
channel
:table_id
--replicate-ignore-table=
channel
:table_id
--replicate-rewrite-db=
channel
:db1-db2
--replicate-wild-do-table=
channel
:table
pattern
--replicate-wild-ignore-table=
channel
:table
pattern
所有这些选项都可以在副本的 my.cnf
文件中使用,就像大多数其他 MySQL 服务器启动选项一样,只需省略前两个连字符。有关简要示例,请参见 复制过滤器和通道概述,以及 6.2.2.2 节,“使用选项文件”。
如果您使用冒号,但不为过滤器选项指定 channel
,例如 --replicate-do-db=:
,则该选项会为默认复制通道配置复制过滤器。默认复制通道是始终存在于启动复制后,与手动创建的多源复制通道不同的复制通道。如果既未指定冒号,也未指定 database_id
channel
,则该选项将配置全局复制过滤器,例如 --replicate-do-db=
会配置全局 database_id
--replicate-do-db
过滤器。
如果您使用相同的 from_name
数据库配置了多个 rewrite-db=
选项,则所有过滤器都会累加(放入 from_name
->to_name
rewrite_do
列表中),并且第一个过滤器会生效。
用于 --replicate-wild-*-table
选项的 pattern
可以包含标识符中允许的任何字符,以及通配符 %
和 _
。这些通配符的使用方式与 LIKE
运算符相同;例如,tbl%
与以 tbl
开头的任何表名匹配,而 tbl_
与 tbl
加一个附加字符匹配的任何表名匹配。
除了 --replicate-*
选项之外,还可以使用 CHANGE REPLICATION FILTER
语句来配置复制过滤器。这消除了重新启动服务器的必要性,但在进行更改时,必须停止复制 SQL 线程。若要使此语句将过滤器应用于特定通道,请使用 FOR CHANNEL
子句。例如channel
CHANGE REPLICATION FILTER REPLICATE_DO_DB=(db1) FOR CHANNEL channel_1;
当提供 FOR CHANNEL
子句时,该语句会作用于指定通道的复制过滤器。如果指定了多种类型的过滤器(do_db
、do_ignore_table
、wild_do_table
等),则只有指定的过滤器类型会被语句替换。在具有多个通道的复制拓扑中(例如,在多源副本上),如果未提供 FOR CHANNEL
子句,则该语句会作用于全局复制过滤器和所有通道的复制过滤器,使用与 FOR CHANNEL
案例类似的逻辑。有关更多信息,请参见 15.4.2.1 节,“CHANGE REPLICATION FILTER 语句”。
配置特定于通道的复制过滤器后,可以通过发出一个空过滤器类型语句来删除该过滤器。例如,若要从名为 channel_1
的复制通道中删除所有 REPLICATE_REWRITE_DB
过滤器,请执行以下操作:
CHANGE REPLICATION FILTER REPLICATE_REWRITE_DB=() FOR CHANNEL channel_1;
使用命令选项或 CHANGE REPLICATION FILTER
配置的任何 REPLICATE_REWRITE_DB
过滤器都会被删除。
RESET REPLICA ALL
语句会删除在该语句删除的通道上设置的特定于通道的复制过滤器。如果已删除的通道被重新创建,则会将为副本指定的任何全局复制过滤器复制到这些通道,并且不会应用任何特定于通道的复制过滤器。