服务器如何评估复制筛选规则
如果主服务器未在其二进制日志中写入一条语句,则不会复制该语句。如果服务器确实记录了该语句,则该语句将发送到所有从属服务器,并且每个从属服务器都决定执行该语句还是忽略它。
在主服务器上,您可以使用--binlog-do-db
和--binlog-ignore-db
选项控制二进制日志,从而控制要记录更改的数据库。有关服务器评估这些选项时使用的规则的说明,请参见“评估数据库级复制和二进制日志记录选项”。您不应使用这些选项来控制要复制的数据库和表。而是在从属服务器上使用筛选来控制在从属服务器上执行的事件。
在从属方,根据--replicate-*
是从属方启动的选项来决定是执行还是忽略从主控方收到的语句。(请参见“复制和二进制日志记录选项和变量”。)也可以使用CHANGE REPLICATION FILTER
语句动态设置由这些选项控制的过滤器。无论是在启动时使用--replicate-*
选项创建还是在从属服务器运行时创建这些过滤器的规则都是相同的CHANGE REPLICATION FILTER
。请注意,复制过滤器不能在配置为组复制的MySQL服务器实例上的特定于组复制的通道上使用,因为在某些服务器上过滤事务将使组无法在一致状态下达成协议。
在最简单的情况下,当没有--replicate-*
选项时,从站将执行从主站接收的所有语句。否则,结果取决于给定的特定选项。
首先检查数据库级别的选项(--replicate-do-db
,--replicate-ignore-db
);有关此过程的说明,请参见“数据库级复制和二进制日志记录选项的评估”。如果未使用数据库级选项,则选项检查将转到可能正在使用的任何表级选项(有关这些选项的讨论,请参见“表级复制选项的评估”)。如果使用了一个或多个数据库级选项,但没有一个被匹配,则不会复制该语句。
对于仅影响数据库语句(即CREATE DATABASE
,DROP DATABASE
和ALTER DATABASE
),数据库级选项总是优先于任何--replicate-wild-do-table
选项。换句话说,对于此类语句,--replicate-wild-do-table
仅当没有适用的数据库级选项时才检查选项。
为了更容易确定选项集将产生什么影响,建议您避免混合使用“ do ”和“ ignore ”选项,或通配符和非通配符选项。
如果--replicate-rewrite-db
指定了任何选项,则会在--replicate-*
测试过滤规则之前应用它们。
所有复制过滤选项均遵循相同的区分大小写规则,该规则适用于MySQL服务器中其他位置的数据库和表的名称,包括lower_case_table_names
系统变量的影响。
评估数据库级复制和二进制日志记录选项
当评估复制选项,从一开始就检查,看看是否有任何--replicate-do-db
或--replicate-ignore-db
适用的选项。使用--binlog-do-db
或时--binlog-ignore-db
,过程类似,但是在母版上检查了选项。
检查数据库是否匹配取决于所处理语句的二进制日志格式。如果该语句已使用行格式记录,则要在其中更改数据的数据库是已检查的数据库。如果已使用语句格式记录了该语句,则默认数据库(使用USE
语句指定)是已检查的数据库。
注意使用行格式只能记录DML语句。DDL语句始终记录为语句,即使
binlog_format=ROW
。因此,始终会根据基于语句的复制规则来过滤所有DDL语句。这意味着您必须使用USE
语句明确选择默认数据库,才能应用DDL语句。
对于复制,此处列出了涉及的步骤:
使用哪种日志格式?
- 声明。测试默认数据库。
- 行。测试受更改影响的数据库。
有什么
--replicate-do-db
选择吗?是。数据库是否与它们中的任何一个匹配?
- 是。继续执行步骤4。
- 否。忽略更新并退出。
- 否。继续执行步骤3。
有什么
--replicate-ignore-db
选择吗?是。数据库是否与它们中的任何一个匹配?
- 是。忽略更新并退出。
- 否。继续执行步骤4。
- 否。继续执行步骤4。
继续检查表级复制选项(如果有)。有关如何检查这些选项的描述,请参见“表级复制选项的评估”。
重要
在此阶段仍允许的语句尚未实际执行。在还检查了所有表级选项(如果有)之后,该语句才执行,并且该过程的结果允许执行该语句。
对于二进制日志记录,此处列出了涉及的步骤:
是否有任何
--binlog-do-db
或--binlog-ignore-db
选择?- 是。继续执行步骤2。
- 否。记录该语句并退出。
是否存在默认数据库(是否选择了任何数据库
USE
)?- 是。继续执行步骤3。
- 否。忽略该语句并退出。
没有默认数据库。有什么
--binlog-do-db
选择吗?是。它们是否与数据库匹配?
- 是。记录该语句并退出。
- 否。忽略该语句并退出。
- 否。继续执行步骤4。
是否有任何
--binlog-ignore-db
选项与数据库匹配?- 是。忽略该语句并退出。
- 否。记录该语句并退出。
重要对于基于语句的日志记录,一个例外是只为给定的规则做
CREATE DATABASE
,ALTER DATABASE
和DROP DATABASE
声明。在这些情况下,在确定是记录日志还是忽略更新时,正在创建,更改或删除的数据库将替换默认数据库。
--binlog-do-db
有时可能意味着“忽略其他数据库”。例如,当使用基于语句的日志记录时,仅运行的服务器--binlog-do-db=sales
不会写入默认数据库不同于的二进制日志语句sales
。当使用具有相同选项的基于行的日志记录时,服务器仅记录那些更改数据的更新sales
。
评估表级复制选项
仅当以下两个条件之一成立时,从属设备才会检查并评估表选项:
- 找不到匹配的数据库选项。
- 找到了一个或多个数据库选项,并根据上一节中所述的规则对其进行了评估,以得出“执行”条件(请参见“数据库级复制和二进制日志记录选项的评估”)。
首先,作为一个初步条件,从服务器检查是否启用了基于语句的复制。如果是这样,并且该语句出现在存储的函数中,则从站执行该语句并退出。如果启用了基于行的复制,则从服务器将不知道是否在主服务器上的存储函数中发生了语句,因此该条件不适用。
注意对于基于语句的复制,复制事件表示语句(组成给定事件的所有更改都与单个SQL语句相关联);对于基于行的复制,每个事件都代表单个表行中的更改(因此,诸如这样的单个语句
UPDATE mytable SET mycol = 1
可能会产生许多基于行的事件)。从事件的角度来看,基于行的复制和基于语句的复制的检查表选项的过程都是相同的。
到此为止,如果没有表选项,则从站仅执行所有事件。如果有任何选项,则要执行的事件必须与其中之一匹配;--replicate-do-table
否则--replicate-wild-do-table
,该事件必须与其中之一匹配。否则,它将被忽略。如果有任何一个--replicate-ignore-table
或--replicate-wild-ignore-table
选项,则执行所有事件,除了那些与这些选项中的任何一个匹配的事件。
以下步骤更详细地描述了此评估。起点是对数据库级选项的评估的结束,如“数据库级复制和二进制日志记录选项的评估”中所述。
有表复制选项吗?
- 是。继续执行步骤2。
- 否。执行更新并退出。
使用哪种日志格式?
- 声明。对执行更新的每个语句执行其余步骤。
- 行。对表行的每次更新执行其余步骤。
有什么
--replicate-do-table
选择吗?是。该表是否与它们中的任何一个匹配?
- 是。执行更新并退出。
- 否。继续执行步骤4。
- 否。继续执行步骤4。
有什么
--replicate-ignore-table
选择吗?是。该表是否与它们中的任何一个匹配?
- 是。忽略更新并退出。
- 否。继续执行步骤5。
- 否。继续执行步骤5。
有什么
--replicate-wild-do-table
选择吗?是。该表是否与它们中的任何一个匹配?
- 是。执行更新并退出。
- 否。继续执行步骤6。
- 否。继续执行步骤6。
有什么
--replicate-wild-ignore-table
选择吗?是。该表是否与它们中的任何一个匹配?
- 是。忽略更新并退出。
- 否。继续执行步骤7。
- 否。继续执行步骤7。
还有另一个要测试的表吗?
- 是。返回步骤3。
- 否。继续执行步骤8。
是否有任何
--replicate-do-table
或--replicate-wild-do-table
选择?- 是。忽略更新并退出。
- 否。执行更新并退出。
如果一个SQL语句上的两个由一个包含一台运行基于语句的复制停止--replicate-do-table
或--replicate-wild-do-table
选项,并且由一个忽略另一个表--replicate-ignore-table
或--replicate-wild-ignore-table
选项。从站必须执行或忽略complete语句(形成复制事件),并且它不能在逻辑上执行此操作。这也适用于DDL语句的基于行的复制,因为DDL语句始终作为语句记录,而不考虑有效的记录格式。可以同时更新包含表和被忽略表并仍能成功复制的唯一类型的语句是已使用以下命令记录的DML语句binlog_format=ROW
。
复制规则应用
本节提供其他说明以及复制过滤选项的不同组合的用法示例。
下表提供了复制过滤器规则类型的一些典型组合:
条件(选项类型) | 结果 |
---|---|
完全没有--replicate-* 选择: | 从机执行从主机接收的所有事件。 |
--replicate-*-db 选项,但没有表格选项: | 从站使用数据库选项接受或忽略事件。因为没有表限制,它将执行那些选项允许的所有事件。 |
--replicate-*-table 选项,但没有数据库选项: | 因为没有数据库条件,所以在数据库检查阶段接受所有事件。从站仅根据表选项执行或忽略事件。 |
数据库和表选项的组合: | 从站使用数据库选项接受或忽略事件。然后,它根据表选项评估这些选项允许的所有事件。有时这会导致结果似乎违反直觉,并且可能会有所不同,具体取决于您使用的是基于语句的复制还是基于行的复制。请参阅文字作为示例。 |
接下来是一个更复杂的示例,其中我们检查了基于语句的设置和基于行的设置的结果。
假设我们mytbl1
在数据库db1
和主mytbl2
数据库db2
上都有两个表,并且从数据库运行以下选项(并且没有其他复制过滤选项):
replicate-ignore-db = db1 replicate-do-table = db2.tbl2
现在,我们在主服务器上执行以下语句:
USE db1;INSERT INTO db2.tbl2VALUES (1);
从站上的结果根据二进制日志格式的不同而有很大差异,在两种情况下都可能不符合初始预期。
基于语句的复制。该USE
语句导致db1
成为默认数据库。因此,该--replicate-ignore-db
选项匹配,并且该INSERT
语句被忽略。表格选项未选中。
基于行的复制。使用基于行的复制时,默认数据库对从属服务器如何读取数据库选项没有影响。因此,该USE
语句在--replicate-ignore-db
选项的处理方式上没有区别:此选项指定的数据库与该INSERT
语句更改数据的数据库不匹配,因此从服务器继续检查表选项。指定--replicate-do-table
的表与要更新的表匹配,并插入行。
基于复制通道的筛选器
本节说明当存在多个复制通道时(例如,在多源复制拓扑中)如何使用复制过滤器。在MySQL 8.0之前,复制过滤器是全局的,因此过滤器已应用于所有复制通道。从MySQL 8.0开始,复制过滤器可以是全局的或特定于通道的,从而使您能够在特定的复制通道上使用复制过滤器配置多源复制从属。当多个主服务器上存在相同的数据库或表时,特定于通道的复制过滤器在多源复制拓扑中特别有用,并且仅要求从服务器从一个主服务器复制它。
有关设置复制通道的说明,请参见“ MySQL多源复制”,有关其工作方式的更多信息,请参见“复制通道”。
重要多源复制从属服务器上的每个通道都必须从其他主服务器复制。即使使用复制筛选器选择要在每个通道上复制的不同数据,也无法设置从单个从属服务器到单个主服务器的多个复制通道。这是因为复制从属服务器的服务器ID在复制拓扑中必须唯一。主服务器仅通过从服务器的服务器ID来区分从服务器,而不能通过复制通道的名称来区分,因此它无法识别来自同一从服务器的不同复制通道。
重要在为组复制配置的MySQL服务器实例上,可以在与组复制不直接相关的复制通道上使用特定于通道的复制筛选器,例如,组成员还充当复制主机的复制从属,组。它们不能在
group_replication_applier
或group_replication_recovery
通道上使用。在这些渠道上进行筛选将使该小组无法就一致的状态达成协议。
复制筛选器和通道概述
当存在多个复制通道时(例如,在多源复制拓扑中),复制过滤器的应用如下:
- 指定的任何全局复制过滤器都将添加到过滤器类型(
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
- 全局复制过滤器:do_db = db1,db3,ignore_db = db4
- channel_1上特定于通道的过滤器:do_db = db2 ignore_db = db4
- 通道 _2上特定于通道的过滤器:do_db = db1,db3 ignore_db = db5
要监视这种设置中的复制过滤器,请使用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 regexid
--replicate-wild-ignore-table=channel:table regexid
例如,如果使用冒号但未channel
为filter选项指定,则该选项为默认复制通道配置复制过滤器。默认复制通道是复制开始后始终存在的复制通道,它不同于您手动创建的多源复制通道。如果既未指定冒号也未指定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
在线更改通道特定的复制筛选器
除了这些--replicate-*
选项之外,还可以使用该CHANGE REPLICATION FILTER
语句配置复制过滤器。这样就无需重新启动服务器,但是在进行更改时必须停止从属应用程序线程。要使该语句将过滤器应用于特定的渠道,请使用该子句。例如: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
情况类似的逻辑作用于全局复制筛选器和所有通道的复制筛选器上。有关更多信息,请参见“ CHANGE REPLICATION FILTER语句”。
删除通道特定的复制筛选器
配置了通道特定的复制筛选器后,可以通过发出空的筛选器类型语句来删除筛选器。例如,REPLICATE_REWRITE_DB
从名为channel_1
issue 的复制通道中删除所有筛选器:
CHANGE REPLICATION FILTER REPLICATE_REWRITE_DB =()FOR CHANNEL channel_1;
REPLICATE_REWRITE_DB
先前使用命令选项或配置的所有过滤器CHANGE REPLICATION FILTER
都将被删除。
该RESET SLAVE ALL
语句将删除在该语句删除的通道上设置的通道特定的复制筛选器。重新创建已删除的一个或多个通道时,将为从属指定的所有全局复制过滤器都复制到它们,并且不应用任何特定于通道的复制过滤器。