本节说明如何在存在多个复制通道时使用复制过滤器,例如在多源复制拓扑中。在 MySQL 8.0 之前,所有的复制过滤器都是全局的,所以过滤器适用于所有的复制通道。从 MySQL 8.0 开始,复制过滤器可以是全局的或特定于通道的,使您能够在特定的复制通道上使用复制过滤器配置多源副本。当同一个数据库或表存在于多个源上时,特定于通道的复制过滤器在多源复制拓扑中特别有用,并且副本只需要从一个源复制它。
有关设置复制通道的说明,请参阅 第 17.1.5 节,“MySQL 多源复制”,有关它们如何工作的更多信息,请参阅 第 17.2.2 节,“复制通道”。
多源副本上的每个通道都必须从不同的源复制。您不能设置从单个副本到单个源的多个复制通道,即使您使用复制过滤器选择不同的数据在每个通道上复制也是如此。这是因为副本的服务器 ID 在复制拓扑中必须是唯一的。源仅通过服务器 ID 来区分副本,而不是通过复制通道的名称来区分副本,因此它无法识别来自同一副本的不同复制通道。
在为组复制配置的 MySQL 服务器实例上,可以在不直接与组复制相关的复制通道上使用特定于通道的复制过滤器,例如组成员也充当组外源的副本. 它们不能用于group_replication_applier
或
group_replication_recovery
频道。在这些渠道上进行过滤将使小组无法就一致的状态达成一致。
对于菱形拓扑中的多源副本(其中副本从两个或多个源复制,而这些源又从公共源复制),当使用基于 GTID 的复制时,确保任何复制过滤器或其他通道配置是在多源副本上的所有通道上都相同。使用基于 GTID 的复制,过滤器仅应用于事务数据,而不会过滤掉 GTID。发生这种情况是为了使副本的 GTID 集与源的保持一致,这意味着可以使用 GTID 自动定位而无需每次都重新获取过滤掉的事务。在下游副本是多源的情况下,在菱形拓扑中从多个源接收相同的交易,下游副本现在有多个版本的交易,结果取决于哪个通道先应用交易。第二个尝试使用 GTID auto-skip 跳过事务的通道,因为事务的 GTID 被添加到
gtid_executed
由第一个通道设置。在通道上进行相同的过滤,没有问题,因为交易的所有版本都包含相同的数据,所以结果是相同的。但是,如果对通道进行不同的过滤,数据库可能会变得不一致并且复制可能会挂起。
当存在多个复制通道时,例如在多源复制拓扑中,复制过滤器应用如下:
指定的任何全局复制过滤器都会添加到过滤器类型(
do_db
、do_ignore_table
等)的全局复制过滤器中。任何特定于通道的复制过滤器都会将过滤器添加到指定通道的指定过滤器类型的复制过滤器中。
如果没有配置这种类型的特定于通道的复制过滤器,则每个复制通道将全局复制过滤器复制到其特定于通道的复制过滤器。
每个通道都使用其特定于通道的复制过滤器来过滤复制流。
创建特定于通道的复制过滤器的语法扩展了现有的 SQL 语句和命令选项。如果未指定复制通道,则配置全局复制过滤器以确保向后兼容。该
CHANGE REPLICATION FILTER
语句支持FOR CHANNEL
在线配置通道特定过滤器的子句。配置过滤器的
--replicate-*
命令选项可以使用以下形式指定复制通道
。假设 channels和
存在于服务器启动之前;在这种情况下,使用命令行选项启动副本
将导致:
--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 服务器启动选项一样,通过省略两个前导破折号。有关简要示例,请参阅
复制过滤器和通道概述,以及第 4.2.2.2 节,“使用选项文件”。
如果您使用冒号但没有
channel
为过滤器选项指定 a,例如
,该选项会为默认复制通道配置复制过滤器。默认复制通道是复制开始后一直存在的复制通道,不同于您手动创建的多源复制通道。当既没有指定冒号也没有指定 a 时,该选项配置全局复制过滤器,例如
配置全局
过滤器。
--replicate-do-db=:
database_id
channel
--replicate-do-db=
database_id
--replicate-do-db
如果您
使用同一个
数据库配置多个选项,则所有过滤器将一起添加(放入
列表中)并且第一个生效。
rewrite-db=
from_name
->to_name
from_name
rewrite_do
pattern
用于选项的
可以--replicate-wild-*-table
包括标识符中允许的任何字符以及通配符
%
和_
。它们的工作方式与与操作员一起使用时的方式相同
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
。有关详细信息,请参阅
第 13.4.2.2 节,“CHANGE REPLICATION FILTER 语句”。
配置特定于通道的复制过滤器后,您可以通过发出空过滤器类型语句来删除过滤器。例如,
REPLICATE_REWRITE_DB
从名为channel_1
问题的复制通道中删除所有过滤器:
CHANGE REPLICATION FILTER REPLICATE_REWRITE_DB=() FOR CHANNEL channel_1;
REPLICATE_REWRITE_DB
之前使用命令选项或配置的
任何过滤器CHANGE REPLICATION FILTER
都将被删除。
该RESET
REPLICA ALL
语句删除在该语句删除的通道上设置的特定于通道的复制过滤器。重新创建已删除的一个或多个通道时,为副本指定的任何全局复制过滤器都会复制到它们,并且不会应用任何通道特定的复制过滤器。