19.2.5.3 复制过滤选项之间的交互
如果您使用数据库级别和表级别的复制过滤选项组合,复制服务器首先根据数据库选项接受或忽略事件,然后根据表选项评估所有允许的事件。这可能会导致结果看起来不太明智。还需要注意的是,结果取决于操作是否使用语句基于或行基于的二进制日志记录格式。如果您想确保复制过滤器始终以相同的方式操作,不管二进制日志记录格式是哪种,特别是如果您使用混合二进制日志记录格式,遵循本主题中的指导。
复制过滤选项的效果在二进制日志记录格式之间不同,因为数据库名称的识别方式不同。使用语句基于格式时,DML语句根据当前数据库指定的数据库来处理。使用行基于格式时,DML语句根据修改表所在的数据库来处理。DDL语句总是根据当前数据库指定的数据库来处理,无论二进制日志记录格式是什么。
涉及多个表的操作也可能会受到复制过滤选项的影响,取决于二进制日志记录格式。需要注意的操作包括涉及多个表的UPDATE语句、触发器、级联外键、存储函数更新多个表、DML语句调用更新一个或多个表的存储函数。如果这些操作更新了过滤器中的表和过滤器外的表,结果可能会因二进制日志记录格式而异。
如果您需要确保复制过滤器始终以相同的方式操作,不管二进制日志记录格式是哪种,特别是如果您使用混合二进制日志记录格式 (binlog_format=MIXED
),请使用表级别的复制过滤选项,不使用数据库级别的复制过滤选项。同时,不要使用多个表的DML语句更新过滤器中的表和过滤器外的表。
如果您需要使用数据库级别和表级别的复制过滤器,并且想这些过滤器以可能的方式操作,可以选择以下策略:
-
如果您使用行基于二进制日志记录格式 (
binlog_format=ROW
),对于DDL语句,依靠USE
语句设置数据库,不指定数据库名称。您可以考虑将二进制日志记录格式更改为行基于格式,以提高复制过滤器的一致性。见Section 7.4.4.2, “Setting The Binary Log Format”了解更改二进制日志记录格式的条件。 -
如果您使用语句基于或混合二进制日志格式(
binlog_format=STATEMENT
或MIXED
),对于 DML 和 DDL 语句,依靠USE
语句,不使用数据库名称。同时,不使用更新过滤器中的和过滤器外的多表 DML 语句。
示例 19.7 --replicate-ignore-db
选项和一个 --replicate-do-table
选项
在复制源服务器上,以下语句被发出:
USE db1;
CREATE TABLE t2 LIKE t1;
INSERT INTO db2.t3 VALUES (1);
复制服务器上设置了以下复制过滤选项:
replicate-ignore-db = db1
replicate-do-table = db2.t3
DDL 语句 CREATE TABLE
在 db1
中创建了表,这是由前面的 USE
语句指定的。复制服务器根据其 --replicate-ignore-db = db1
选项将过滤掉这个语句,因为 db1
是当前数据库。这在任何二进制日志格式下都是一样的结果。然而,DML INSERT
语句的结果根据二进制日志格式不同:
-
如果源服务器使用行基于二进制日志格式(
binlog_format=ROW
),复制服务器使用数据库中存在的表的数据库来评估INSERT
操作,该表名为db2
。数据库级别选项--replicate-ignore-db = db1
首先被评估,因此不适用。表级别选项--replicate-do-table = db2.t3
适用,因此复制服务器将应用更改到表t3
。 -
如果源端使用语句基于的二进制日志格式(
binlog_format=STATEMENT
),复制服务器将根据默认数据库对INSERT
操作进行评估,该数据库由USE
语句设置为db1
,并且没有被更改。根据复制服务器的数据库级别--replicate-ignore-db = db1
选项,它因此忽略操作,不将更改应用于表t3
。表级选项--replicate-do-table = db2.t3
不被检查,因为语句已经匹配了数据库级别选项并被忽略。
如果复制服务器上的--replicate-ignore-db = db1
选项必要,并且源端使用语句基于(或混合)二进制日志格式也必要,可以通过在INSERT
语句中省略数据库名称,并依靠USE
语句来实现一致性,如下所示:
USE db1;
CREATE TABLE t2 LIKE t1;
USE db2;
INSERT INTO t3 VALUES (1);
在这种情况下,复制服务器总是根据数据库db2
对INSERT
语句进行评估,无论操作是否在语句基于或行基于的二进制日志格式中记录,结果都相同。