副本仅在满足以下两个条件之一时才会检查和评估表选项:
没有找到匹配的数据库选项。
找到一个或多个数据库选项,并且根据上一节(参见 第 19.2.5.1 节,“数据库级复制和二进制日志选项的评估”)中描述的规则评估为“执行”条件。
首先,作为预备条件,副本会检查是否启用了基于语句的复制。如果是,并且语句发生在存储函数内,则副本会执行该语句并退出。如果启用了基于行的复制,则副本不知道语句是否在源上发生在存储函数内,因此此条件不适用。
对于基于语句的复制,复制事件表示语句(构成给定事件的所有更改都与单个 SQL 语句相关联);对于基于行的复制,每个事件都表示单个表行的更改(因此单个语句,例如 UPDATE mytable SET mycol = 1
可能会产生许多基于行的事件)。从事件的角度来看,检查表选项的过程对于基于行和基于语句的复制都是一样的。
到达此步骤后,如果没有表选项,则副本会简单地执行所有事件。如果有任何 --replicate-do-table
或 --replicate-wild-do-table
选项,则事件必须与其中之一匹配才能执行;否则,它将被忽略。如果有任何 --replicate-ignore-table
或 --replicate-wild-ignore-table
选项,则会执行所有事件,除了与这些选项中的任何一个匹配的事件。
表级复制过滤器仅应用于查询中明确提及和操作的表。它们不应用于由查询隐式更新的表。例如,GRANT
语句更新了 mysql.user
系统表,但没有提及该表,不受指定 mysql.%
作为通配符模式的过滤器的影响。
以下步骤更详细地描述了此评估。起点是数据库级选项评估的结束,如 第 19.2.5.1 节,“数据库级复制和二进制日志选项的评估” 中所述。
是否有任何表复制选项?
是。 继续执行步骤 2。
否。 执行更新并退出。
使用哪种日志记录格式?
STATEMENT。 对执行更新的每个语句执行剩余步骤。
ROW。 对每个表行的更新执行剩余步骤。
是否有任何
--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
选项忽略的表,则基于语句的复制会停止。副本必须执行或忽略整个语句(构成一个复制事件),而不能逻辑地做到这一点。这也适用于基于行的复制的 DDL 语句,因为 DDL 语句始终记录为语句,而不考虑生效的日志格式。唯一可以更新包含表和忽略表并仍成功复制的语句类型是使用 binlog_format=ROW
记录的 DML 语句。