如果您结合使用数据库级和表级复制过滤选项,则副本首先使用数据库选项接受或忽略事件,然后根据表选项评估这些选项允许的所有事件。这有时会导致看似违反直觉的结果。同样重要的是要注意,结果会有所不同,具体取决于操作是使用基于语句还是基于行的二进制日志记录格式进行记录。如果您想确保您的复制过滤器始终以相同的方式独立于二进制日志记录格式运行,这在您使用混合二进制日志记录格式时尤为重要,请遵循本主题中的指导。
由于识别数据库名称的方式不同,复制过滤选项的效果因二进制日志记录格式而异。使用基于语句的格式,DML 语句根据语句指定的当前数据库进行处理
USE
。使用基于行的格式,DML 语句根据修改表所在的数据库进行处理。DDL 语句始终根据
USE
语句指定的当前数据库进行过滤,而不管二进制日志记录格式如何。
根据二进制日志记录格式,复制过滤选项也会对涉及多个表的操作产生不同的影响。需要注意的操作包括涉及多表
UPDATE
语句、触发器、级联外键、更新多个表的存储函数以及调用更新一个或多个表的存储函数的 DML 语句的事务。如果这些操作同时更新过滤入表和过滤出表,则结果可能会因二进制日志记录格式而异。
如果您需要保证您的复制过滤器始终如一地运行,而不管二进制日志记录格式如何,特别是如果您使用混合二进制日志记录格式 ( binlog_format=MIXED
),请仅使用表级复制过滤选项,而不要使用数据库级复制过滤选项。此外,不要使用同时更新滤入表和滤出表的多表 DML 语句。
如果您需要结合使用数据库级和表级复制过滤器,并希望它们尽可能一致地运行,请选择以下策略之一:
如果使用基于行的二进制日志记录格式(
binlog_format=ROW
),对于 DDL 语句,依赖USE
语句设置数据库并且不指定数据库名称。您可以考虑更改为基于行的二进制日志记录格式,以提高与复制过滤的一致性。有关适用于更改二进制日志记录格式的条件,请参阅 第 5.4.4.2 节,“设置二进制日志格式”。如果您使用基于语句或混合二进制日志记录格式(
binlog_format=STATEMENT
或MIXED
),对于 DML 和 DDL 语句,请依赖USE
语句而不使用数据库名称。此外,不要使用同时更新滤入表和滤出表的多表 DML 语句。
例 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
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);
在这种情况下,副本始终
INSERT
根据数据库评估语句db2
。无论操作是以基于语句还是基于行的二进制格式记录的,结果都保持不变。