16.2.5.3 复制过滤选项之间的交互

如果您使用数据库级复制过滤选项和 table 级复制过滤选项的组合,则副本首先使用数据库选项接受或忽略事件,然后它将根据 table 选项评估这些选项允许的所有事件。有时这可能会导致结果似乎违反直觉。同样重要的是要注意,结果是根据使用基于语句的还是基于行的二进制日志记录格式来记录操作而变化的。如果要确保复制筛选器始终以相同的方式独立于二进制日志记录格式运行,这在使用混合二进制日志记录格式时尤其重要,请遵循本主题中的指导。

复制筛选选项的效果在二进制日志记录格式之间有所不同,这是因为标识数据库名称的方式不同。使用基于语句的格式,DML 语句将根据USE语句指定的当前数据库进行处理。使用基于行的格式时,DML 语句将基于已修改 table 所在的数据库进行处理。不管二进制日志记录格式如何,总是根据USE语句指定的当前数据库来过滤 DDL 语句。

涉及二进制 table 的操作也可能会受到二进制筛选格式的复制筛选选项的不同影响。需要注意的操作包括涉及多 tableUPDATE语句的事务,触发器,级联外键,更新多个 table 的存储函数以及调用更新一个或多个 table 的存储函数的 DML 语句。如果这些操作同时更新了过滤 table 和过滤 table,则结果可能会随二进制日志记录格式而变化。

如果您需要确保复制过滤器无论二进制日志记录格式如何均能始终如一地运行,尤其是在使用混合二进制日志记录格式(binlog_format=MIXED)的情况下,请仅使用 table 级复制过滤选项,而不使用数据库级复制过滤选项。另外,请勿使用同时更新已过滤 table 和已过滤 table 的多 tableDML 语句。

如果需要结合使用数据库级和 table 级复制筛选器,并希望它们尽可能一致地运行,请选择以下策略之一:

  • 如果使用基于行的二进制日志记录格式(binlog_format=ROW),则对于 DDL 语句,请依靠USE语句设置数据库,而不指定数据库名称。您可以考虑更改为基于行的二进制日志记录格式,以提高与复制过滤的一致性。有关适用于更改二进制日志记录格式的条件,请参见第 5.4.4.2 节“设置二进制日志格式”

  • 如果对 DML 和 DDL 语句使用基于语句的或混合的二进制日志记录格式(binlog_format=STATEMENTMIXED),则都依赖USE语句,而不使用数据库名称。另外,请勿使用同时更新已过滤 table 和已过滤 table 的多 tableDML 语句。

范例 16.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

如前面的USE语句所指定,DDL 语句CREATE TABLEdb1中创建 table。复制副本根据其--replicate-ignore-db = db1选项过滤掉该语句,因为db1是当前数据库。无论源中的二进制日志记录格式如何,此结果都是相同的。但是,DML INSERT语句的结果因二进制日志记录格式而异:

如果副本服务器上的--replicate-ignore-db = db1选项是必需的,并且源服务器上也需要使用基于语句的(或混合的)二进制日志记录格式,则可以通过从INSERT语句中省略数据库名称并依赖于USE语句改为如下:

USE db1;
CREATE TABLE t2 LIKE t1;
USE db2;
INSERT INTO t3 VALUES (1);

在这种情况下,副本始终基于数据库db2评估INSERT语句。无论该操作是以基于语句的二进制格式还是基于行的二进制格式记录,结果都将保持不变。