准备要处理的表
本节介绍如何准备要处理的表。表准备需要执行以下任务。
确保表的行唯一性
Oracle GoldenGate 在源表和目标表上需要某种形式的唯一行标识符,以查找用于复制更新和删除的正确目标行。
除非 TABLE 或 MAP 语句中使用 KEYCOLS 子句,否则 Oracle GoldenGate 将按以下优先级顺序选择要使用的行标识符:
-
主键
-
按字母数字顺序排列的第一个不包含时间戳或非实体化计算列的唯一键。
-
如果上述关键字类型均不存在(即使表中可能定义了其他类型的关键字),则 Oracle GoldenGate 将构造所有列的伪关键字数据库允许在唯一密钥中使用,但不包括 Oracle GoldenGate 在密钥中不支持的密钥或从 Oracle GoldenGate 配置中排除的密钥。
注:如果表中存在其他不可使用的关键字,或者表中根本没有关键字,则 Oracle GoldenGate 会将相应的消息记录到报表文件中。从所有列构建密钥会妨碍 Oracle GoldenGate 在源系统上的性能。在目标上,此键会导致复制使用较大且效率较低的 WHERE 子句。
- 如果表没有相应的键,或者您希望未使用现有键,则可以定义替代键(如果表具有始终包含唯一值的列)。可以通过在 Extract
TABLE参数和 ReplicatMAP参数中包含KEYCOLS子句来定义此替代关键字。指定的键将覆盖 Oracle GoldenGate 找到的任何现有主键或唯一键。请参阅 Reference for Oracle GoldenGate 中的 TABLE | MAP 。
具有从唯一索引派生的主键的表
如果表中没有主键,如果索引列为 NOT NULL,则 MySQL 会将唯一索引提升为主键。如果这些非空索引中有多个,则创建的第一个非空索引将成为主键。为了避免复制错误,请在源表和目标表上按相同的顺序创建这些索引。
例如,假定名为 ggvam.emp 的源表和目标表都具有名为 first、middle 和 last 的列,并且所有表都定义为 NOT NULL。如果按以下顺序创建唯一索引,则 Oracle GoldenGate 将异常终止目标,因为表定义不匹配。
来源:
CREATE UNIQUE INDEX UQL ON ggvam.emp(first);
CREATE UNIQUE INDEX UQ2 on ggvam.emp(middle);
CREATE UNIQUE INDEX UQ3 on ggvam.emp(last);
目标:
CREATE UNIQUE INDEX UQ1 ON ggvam.emp(last);
CREATE UNIQUE INDEX UQ2 ON ggvam.emp(first);
CREATE UNIQUE INDEX UQ3 ON ggvam.emp(middle);
此序列的结果是 MySQL 将源 "first" 列上的索引提升为主键,并将目标 "last" 列上的索引提升为主键。Oracle GoldenGate 在构建其元数据记录时将选择主键作为标识符,并且元数据将不匹配。要避免此错误,请确定要提升为主键的列,并首先在源和目标上创建该索引。
指定您自己的密钥以供 Oracle GoldenGate 使用
如果表没有上述行标识符类型之一,或者您希望不使用这些标识符,则可以定义替代键(如果表具有始终包含唯一值的列)。通过在 Extract TABLE 参数和 Replicat MAP 参数中包含 KEYCOLS 子句,可以定义此替代关键字。指定的键将覆盖 Oracle GoldenGate 找到的任何现有主键或唯一键。
限制没有关键字的表的行更改
如果目标表没有主键或唯一键,则可能存在重复的行。在这种情况下,Oracle GoldenGate 可能会更新或删除太多的目标行,从而导致源和目标数据不同步,而不会发出错误消息来向您发出预警。要限制更新的行数,请在 Replicat 参数文件中使用带有 LIMITROWS 选项的 DBOPTIONS 参数。LIMITROWS 可以提高 Oracle GoldenGate 在目标系统上的性能,因为仅处理一行。
触发和级联约束条件注意事项
触发器
禁用目标表中的触发器,或对其进行更改以忽略 Oracle GoldenGate 数据库用户所做的更改。Oracle GoldenGate 将复制由触发器生成的 DML。如果在目标表上激活了相同的触发器,则由于复制的版本,该触发器将变得冗余,并且数据库将返回错误。
级联约束条件注意事项
Oracle GoldenGate 捕获的级联更新和删除不会记录在二进制日志中,因此不会捕获这些更新和删除。这对 MySQL 和 MariaDB 均有效。例如,在父表中运行删除语句时,如果表之间存在父子关系,则会对子表执行级联删除(如果存在),但不会将其记录在二进制日志中。只有父表的删除或更新记录会记录在二进制日志中,并由 Oracle GoldenGate 捕获。
有关详细信息,请参见 https://mariadb.com/kb/en/replication-and-foreign-keys/ 和 https://dev.mysql.com/doc/refman/8.0/en/innodb-and-mysql-replication.html 。
要正确处理级联操作的复制,建议在修改父记录之前禁用对应用程序的源和代码的级联删除和更新,以显式删除或更新子记录。或者,必须确保目标父表与源父表配置相同的级联约束条件,但这可能会导致源和目标之间出现不同步情况,尤其是在双向复制的情况下。