19.2.5.4 多源复制 Channel 基于过滤器
本节解释了如何在存在多个复制通道的情况下使用复制过滤器,例如在多源复制拓扑结构中。复制过滤器可以是全局的,也可以是特定于通道的,允许您在多源复制拓扑结构中配置多源复制过滤器在特定复制通道上。通道特定的复制过滤器在多源复制拓扑结构中特别有用,因为在该拓扑结构中,同一个数据库或表可能出现在多个源上,而复制器只需要从一个源复制它。
要了解如何设置复制通道,请见第19.1.5节,“MySQL 多源复制”,了解它们的工作原理,请见第19.2.2节,“复制通道”。
每个多源复制通道都必须从不同的源复制。您不能在单个复制器上设置多个复制通道,即使使用过滤器选择不同的数据在每个通道上。这是因为服务器ID必须在复制拓扑结构中唯一。源服务器只能通过服务器ID来识别复制器,而不是通过复制通道的名称,因此不能识别来自同一个复制器的不同复制通道。
在 MySQL 服务器实例上配置了 Group Replication 的情况下,可以在不直接参与 Group Replication 的复制通道上使用通道特定的复制过滤器,例如在一个组成员同时作为一个源服务器的复制器,来自外部的源服务器。这些过滤器不能用于 group_replication_applier
或 group_replication_recovery
通道上。将过滤器应用于这些通道将使得组无法达成一致的状态。
在多源复制拓扑结构中,diamond拓扑结构(其中复制器从两个或多个源复制,源服务器又从一个公共源复制),使用 GTID-基于的复制时,确保在所有通道上都具有相同的过滤器或其他通道配置。使用 GTID-基于的复制时,过滤器只应用于事务数据,而 GTIDs 不会被过滤。这是因为复制器的 GTID 集合保持一致,以便使用 GTID 自动定位不需要重新获取过滤出的事务。对于在 diamond 拓扑结构中,下游复制器从多个源接收同一个事务,在这种情况下,下游复制器现在拥有多个版本的事务,结果取决于哪个通道首先应用事务。第二个通道尝试应用事务时,使用 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 服务器启动选项一样,通过省略前两个减号。见复制过滤器和通道概述,了解更多信息,以及Section 6.2.2.2,“使用选项文件”。
如果您使用冒号,但没有指定channel
,例如--replicate-do-db=:
,该选项将配置默认复制通道的复制过滤器。默认的复制通道是 replication channel,总是存在于复制启动后,并且不同于手动创建的多源复制通道。没有指定冒号或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
开头的表名加一个额外的字符。
在线更改 Channel 特定 复制过滤器
除了--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 Statement”。
删除 Channel 特定 复制过滤器
当 Channel 特定 复制过滤器已经配置时,可以通过发放空过滤器类型语句来删除过滤器。例如,要删除名为channel_1
的复制渠道上的所有REPLICATE_REWRITE_DB
过滤器,请发放:
CHANGE REPLICATION FILTER REPLICATE_REWRITE_DB=() FOR CHANNEL channel_1;
之前配置的所有REPLICATE_REWRITE_DB
过滤器将被删除。
RESET REPLICA ALL
语句删除了 Channel 特定 复制过滤器,这些过滤器是在语句中删除的渠道或渠道上配置的。当删除的渠道或渠道重新创建时,任何全局复制过滤器指定的副本将被复制到它们,并且不应用 Channel 特定 复制过滤器。