如果您使用数据库级别和表级别复制过滤选项的组合,副本首先根据数据库选项接受或忽略事件,然后根据表选项评估所有事件。如果您想确保您的复制过滤器始终以相同的方式独立于二进制日志记录格式操作,特别是在使用混合二进制日志记录格式时,请遵循本主题中的指导。
复制过滤选项的效果因二进制日志记录格式而异,因为数据库名称的标识方式不同。使用语句基于格式,DML 语句基于当前数据库,指定为 USE
语句。使用行基于格式,DML 语句基于修改的表所在的数据库。DDL 语句总是基于当前数据库,指定为 USE
语句,无论二进制日志记录格式如何。
涉及多个表的操作也可能因复制过滤选项和二进制日志记录格式而异。需要注意的操作包括事务涉及多表 UPDATE
语句、触发器、级联外键、存储函数更新多个表和 DML 语句调用更新一个或多个表的存储函数。如果这些操作更新了既过滤入又过滤出的表,结果将因二进制日志记录格式而异。
如果您需要确保您的复制过滤器在任何二进制日志记录格式下都能一致地操作,特别是在使用混合二进制日志记录格式 (binlog_format=MIXED
),请仅使用表级别复制过滤选项,不要使用数据库级别复制过滤选项。此外,不要使用更新既过滤入又过滤出的表的多表 DML 语句。
如果您需要使用数据库级别和表级别复制过滤器的组合,并想使它们尽可能一致地操作,可以选择以下策略:
-
如果您使用行基于二进制日志记录格式 (
binlog_format=ROW
),对于 DDL 语句,请使用USE
语句设置数据库,不要指定数据库名称。您可以考虑更改为行基于二进制日志记录格式,以提高与复制过滤的一致性。请参阅 第 7.4.4.2 节,“设置二进制日志格式”,了解更改二进制日志记录格式的条件。 -
如果您使用语句基于或混合二进制日志记录格式 (
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
),则副本根据表所在的数据库名称db2
来评估INSERT
操作。数据库级选项--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
语句。无论操作是否以基于语句或基于行的二进制日志格式记录,结果保持不变。