【真实经验分享】Oracle GoldenGate Replicat Abend:Key Column Missing 根因分析与修复 一、故障现象某生产环境 Oracle GoldenGate 19c 的 Replicat 进程REP_LIB突然 AbendReport 日志抛出核心错误ERROR OGG-01296 Error mapping from [SRC_SCHEMA].SRTCONTAINER to [TGT_SCHEMA].SRTCONTAINER. ERROR OGG-01668 PROCESS ABENDING.进程停止前最后一条有效警告WARNING OGG-01431 Aborted grouped transaction on [TGT_SCHEMA].SRTCONTAINER, Mapping error. WARNING OGG-01151 Error mapping from [SRC_SCHEMA].SRTCONTAINER to [TGT_SCHEMA].SRTCONTAINER.同时discard 文件记录了决定性线索Key column DATAID (0) is missing from update on table [TGT_SCHEMA].SRTCONTAINER Missing 1 key columns in update for table [TGT_SCHEMA].SRTCONTAINER.二、环境信息组件版本/信息OGG 版本19.1.0.0.4操作系统Linux x86_64源端数据库Oracle 19c字符集 ZHS16GBK目标端数据库Oracle 19c字符集 ZHS16GBKReplicat 类型Classic Replicat三、排查过程3.1 第一步查看 Discard 文件Discard 文件是第一现场。与常见的ORA-00001唯一冲突或ORA-12899值太大不同这次 discard 没有任何 Oracle 错误号而是直接指出Key column DATAID is missing from update这说明 Replicat 在构建UPDATE ... WHERE语句时发现定位行所需的键列DATAID在 trail 记录中不存在导致无法定位目标行。3.2 第二步对比源端与目标端表结构分别检查源端和目标端的SRTCONTAINER表结论列名、列顺序、数据类型完全一致但 NOT NULL 约束不同。更关键的是索引差异源端索引TR_SRTCONTAINER_PK SRTCONTAINERID UNIQUE目标端索引PK_SRTCONTAINER DATAID, SRTCONTAINERID UNIQUE发现源端业务主键是单列SRTCONTAINERID目标端主键是复合主键(DATAID, SRTCONTAINERID)3.3 第三步检查 OGG 自动识别的 Key ColumnsReplicat 启动日志明确显示INFO OGG-06510 Using the following key columns for target table [TGT_SCHEMA].SRTCONTAINER: DATAID, SRTCONTAINERID.OGG 自动识别了目标端的复合主键并将其作为该表的Key Columns用于在目标端定位行的列。3.4 第四步检查源端补充日志SELECTSUPPLEMENTAL_LOG_DATA_PKFROMV$DATABASE;-- 结果NO源端数据库未开启主键补充日志。四、根因分析4.1 OGG 的 Key Columns 识别机制在 Classic Replicat 中OGG 会按以下优先级自动确定目标表的 Key Columns目标端的主键Primary Key目标端的唯一索引Unique Index目标端所有 NOT NULL 列本案例中目标端存在复合主键PK_SRTCONTAINER(DATAID, SRTCONTAINERID)因此 OGG 自动将DATAID和SRTCONTAINERID同时作为 Key Columns。4.2 压缩更新与 Trail 记录内容OGG Extract 默认使用**压缩更新Compressed Updates**模式。对于一条UPDATE语句trail 中通常只包含被修改的列After ImageKey Columns用于在目标端定位行的列取自源端的主键/唯一索引问题就出在这里端主键/唯一键对 OGG 的意义源端TR_SRTCONTAINER_PK(SRTCONTAINERID)Extract 认为 Key SRTCONTAINERID因此 trail 中只保证携带SRTCONTAINERID目标端PK_SRTCONTAINER(DATAID, SRTCONTAINERID)Replicat 认为 Key DATAIDSRTCONTAINERID构建 SQL 时需要这两个值当源端执行如下 UPDATE 时UPDATESRTCONTAINERSETUPDATETIME...,UPDATER...,STATUS...WHERESRTCONTAINERID...;DATAID既不是被修改的列也不是源端的主键/唯一索引列在压缩更新模式下Extract不会将 DATAID 写入 trailReplicat 收到记录后发现需要DATAID来构建WHERE DATAID ? AND SRTCONTAINERID ?但 trail 中没有 → 报错Key column DATAID is missing4.3 补充日志的角色源端SUPPLEMENTAL_LOG_DATA_PK NO意味着 Oracle redo 不会强制记录主键列的完整前像。虽然即使开启 PK 补充日志由于DATAID并非源端主键的一部分依然无法解决DATAID缺失的问题但未开启补充日志确实是 OGG 部署的一个潜在风险点它限制了 Extract 在更复杂场景下获取完整键值的能力。4.4 根因总结图源端 UPDATE (只改 UPDATER/STATUS/UPDATETIME) │ ▼ Extract 识别源端 Key SRTCONTAINERID │ ▼ Trail 记录包含修改列 SRTCONTAINERID │ ▼ Replicat 识别目标端 Key DATAID SRTCONTAINERID │ ▼ 构建 UPDATE ... WHERE DATAID? AND SRTCONTAINERID? │ ▼ Trail 中无 DATAID ────────► Key column DATAID is missing │ ▼ OGG-01296 Mapping Error │ ▼ OGG-01668 PROCESS ABENDING一句话根因目标端复合主键包含的DATAID列在源端 UPDATE 产生的 trail 记录中缺失导致 Replicat 无法构建完整的行定位条件。五、解决方案5.1 方案选择由于源端业务上SRTCONTAINERID已能唯一标识一行源端有唯一索引且目标端验证无重复值最简洁的方案是在 Replicat 参数中显式覆盖自动识别的 Key Columns强制只使用SRTCONTAINERID定位MAP[SRC_SCHEMA].SRTCONTAINER, TARGET[TGT_SCHEMA].SRTCONTAINER, KEYCOLS(SRTCONTAINERID);注意该参数必须放在通配符MAP [SRC_SCHEMA].*.*之前否则会被通配符抢先匹配。5.2 为什么不选其他方案方案说明未选原因修改目标表结构去掉DATAID或改为单列主键涉及业务系统改造风险极高5.3 参数修改示例REPLICAT rep_lib SETENV(ORACLE_HOME$ORACLE_HOME)SETENV(ORACLE_SID[DB_NAME])SETENV(NLS_LANGAMERICAN_AMERICA.ZHS16GBK)USERID[OGG_USER]password *** ASSUMETARGETDEFS DBOPTIONS DEFERREFCONST DBOPTIONS SUPPRESSTRIGGERS DISCARDFILE ./dirrpt/rep_lib.dsc, APPEND, MEGABYTES1000REPERROR(DEFAULT, ABEND)DDL INCLUDE MAPPED, OBJTYPETABLEINCLUDE MAPPED OBJTYPEINDEXGROUPTRANSOPS1000-- 显式指定 Key Columns必须放在通配符之前 MAP[SRC_SCHEMA].SRTCONTAINER, TARGET[TGT_SCHEMA].SRTCONTAINER, KEYCOLS(SRTCONTAINERID);-- 通配符映射 MAP[SRC_SCHEMA].*.*, TARGET[TGT_SCHEMA].*.*;...修改后重启GGSCIstop rep_lib GGSCIstart rep_lib六、经验总结与最佳实践6.1 源端与目标端主键不一致是常见陷阱在异构同步或数仓场景中目标端常会增加代理键、分区键或数据仓库键形成与源端不同的主键结构。OGG 默认按目标端约束识别 Key Columns一旦目标端主键列在源端 trail 中无法获取就会触发本案例的故障。建议在 OGG 投产前梳理所有同步表的源端/目标端主键差异对不一致的表提前配置KEYCOLS或FETCHCOLS。6.2 补充日志是 OGG 的基石虽然本次故障的直接原因不是补充日志但SUPPLEMENTAL_LOG_DATA_PK NO是一个显著风险。建议源端开启ALTERDATABASEADDSUPPLEMENTAL LOGDATA(PRIMARYKEY)COLUMNS;这能确保 Extract 在绝大多数场景下获取到完整的主键值。6.3 Discard 文件是排障的第一现场遇到 Mapping Error 时不要只看 Report 日志的OGG-01296一定要第一时间查看 discard 文件。discard 中的Key column XXX is missing直接指明了缺失的列能大幅缩短排障路径。6.4 KEYCOLS 的适用边界使用KEYCOLS强制指定定位列时必须确保该列在业务上真正唯一。修改前应在目标端验证SELECTSRTCONTAINERID,COUNT(*)FROM[TGT_SCHEMA].SRTCONTAINERGROUPBYSRTCONTAINERIDHAVINGCOUNT(*)1;返回no rows selected方可安全使用。关键词Oracle GoldenGate, Replicat Abend, OGG-01296, Key Column Missing, COMPRESSUPDATES, Supplemental Log, KEYCOLS, Mapping Error