本节说明了在存在多个复制通道的情况下如何使用复制过滤器,例如在多源复制拓扑中。复制过滤器可以是全局的,也可以是特定于通道的,使您能够配置多源副本,并在特定的复制通道上使用复制过滤器。特定于通道的复制过滤器在多源复制拓扑中特别有用,当多个源存在相同的数据库或表时,副本只需要从一个源复制它。
有关设置复制通道的说明,请参见 第 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
语句会删除通过该语句删除的通道上设置的特定于通道的复制过滤器。当删除的通道重新创建时,副本指定的任何全局复制过滤器都会复制到这些通道,并且不会应用任何特定于通道的复制过滤器。