本节解释了如何在存在多个复制通道的情况下使用复制过滤器,例如在多源复制拓扑结构中。复制过滤器可以是全局的或特定于通道的,启用您在特定复制通道上配置多源复制副本的复制过滤器。通道特定的复制过滤器在多源复制拓扑结构中非常有用,当同一个数据库或表出现在多个源上时,副本只需要从一个源复制它。
有关设置复制通道的说明,请参阅 第 19.1.5 节,“MySQL 多源复制”,有关它们如何工作的更多信息,请参阅 第 19.2.2 节,“复制通道”。
在多源副本上,每个通道必须从不同的源复制。您不能设置从单个副本到单个源的多个复制通道,即使您使用复制过滤器来选择每个通道上的不同数据。这是因为副本的服务器 ID 在复制拓扑结构中必须是唯一的。源服务器只能通过副本的服务器 ID 来区分副本,而不是通过复制通道的名称。
在配置了组复制的 MySQL 服务器实例上,通道特定的复制过滤器可以在不直接参与组复制的复制通道上使用,例如在组成员也作为外部源的副本时。但是,它们不能在 group_replication_applier
或 group_replication_recovery
通道上使用。这些通道上的过滤将使组无法达成一致的状态。
对于多源副本在菱形拓扑结构中(其中副本从两个或多个源复制,而这些源又从公共源复制),当使用基于 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
-
通道特定过滤器 on channel_1:
do_db=db2
;ignore_db=db4
;wild-do-table=db6.t1%
-
通道特定过滤器 on 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 服务器启动选项,通过省略两个前导破折号。请参阅 Overview of Replication Filters and Channels,以获取简要示例,以及 Section 6.2.2.2, “Using Option Files”。
如果您使用冒号但不指定channel
用于过滤器选项,例如 --replicate-do-db=:
,则该选项将配置默认复制通道的复制过滤器。默认复制通道是始终存在的一条复制通道,一旦复制开始,它不同于手动创建的多源复制通道。当既不指定冒号也不指定database_id
channel
时,该选项将配置全局复制过滤器,例如 --replicate-do-db=
将配置全局 database_id
--replicate-do-db
过滤器。
如果您配置了多个 rewrite-db=
选项,具有相同的 from_name
->to_name
from_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.2 节,“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
语句将删除由该语句删除的通道上的通道特定复制过滤器。当删除的通道或通道重新创建时,任何全局复制过滤器都将被复制到它们上,并且不应用通道特定复制过滤器。