ARTICLE DETAIL

资讯详情

深耕网站SEO优化与搜索引擎排名提升的一线实战洞察。

OGG Replicat数据过滤完全指南:FILTER与WHERE实战解析

OGG Replicat数据过滤完全指南:FILTER与WHERE实战解析 在Oracle GoldenGate的数据同步实践中并非所有源端数据都需要原封不动地同步到目标端。业务场景中常见的数据过滤需求多种多样只同步满足特定条件的业务数据、按数据范围拆分同步任务以实现并行复制、在指定CSN点启动复制进程处理断点续传。这些场景都离不开Replicat进程的FILTER功能。FILTER与WHERE是OGG中最核心的数据过滤手段。FILTER能够调用OGG内置的列转换函数具备更强的灵活性WHERE则只接受基本的比较运算符。一个常见的误区是很多DBA只在Extract端做过滤却忽略了在Replicat端做过滤的独特价值。在数据泵或Replicat端过滤数据可以减少网络传输量降低目标端数据库负载实现更精细的数据分发控制。一、FILTER与WHERE的区别与选型1.1 功能差异对比在OGG中FILTER和WHERE都可以在TABLE或MAP语句中实现行级过滤但两者有本质区别。FILTER的强大之处在于可以使用OGG所有的列转换函数包括STRFIND、RANGE、GETENV等。这意味着你可以实现模糊匹配、按哈希范围拆分、基于环境变量的动态过滤等高级场景。FILTER的工作机制是在记录从源端捕获后、写入目标端之前进行过滤判断只有满足条件的记录才被写入目标端。FILTER支持的操作符包括算术运算符、-、*、/、\以及比较运算符、、、、、还支持使用AND、OR进行逻辑组合。根据Oracle官方文档FILTER还支持ON INSERT、ON UPDATE、ON DELETE选项可以指定FILTER针对哪些SQL操作类型生效。例如可以在UPDATE操作时触发过滤而INSERT操作不受影响。此外FILTER还支持RAISEERROR选项当过滤失败时可以生成用户自定义的错误信息这在需要触发事件响应的场景中非常有用。WHERE则相对简单只支持基本的比较运算符如、、、、AND、OR以及NULL判断。WHERE不支持函数调用因此无法实现模糊查询或多条件复杂组合。根据官方文档WHERE不支持算术运算符和浮点数据类型也不支持多字节字符集或不兼容字符集的列。在实战中当需要过滤job_id like AD_VP这类模糊匹配条件时WHERE无法直接满足必须使用FILTER结合STRFIND函数来实现。1.2 性能考量从性能角度看在Extract端过滤是最优选择因为数据在源端被捕获时即被过滤后续的传输和写入环节都不会携带被过滤的数据。在数据泵中过滤则是次优选择因为数据仍然需要从源端传输到中间节点。Oracle官方文档明确指出数据过滤和数据转换都会增加系统开销并且有时容易导致配置错误。如果需要执行大量的过滤和转换操作建议使用一个或多个数据泵来处理这部分工作。在Replicat端过滤需要Replicat读取所有GoldenGate trail数据来寻找满足条件的记录然后丢弃不满足条件的记录这会导致网络传输量增加。但Replicat端过滤的优势在于可以与目标端解耦便于根据目标端的业务特点进行精细化的数据分发控制。此外当使用RANGE函数时在Extract端计算范围比在Replicat端计算更高效。在目标端计算范围需要Replicat读取所有trail数据来找到满足每个范围规范的数据。二、Replicat端FILTER的实战场景2.1 基于字符匹配的数据过滤在OGG中标准SQL中的LIKE模糊匹配并不被直接支持。当需要过滤job_id以特定字符串开头的记录时需要使用STRFIND函数配合FILTER实现。以下示例展示了如何过滤job_id以AD_VP开头的记录MAP pdb1.hr.employees, TARGET orclpdb.user1.employees, FILTER (STRFIND(job_id, AD_VP) 0);当需要多个模糊条件组合时例如job_id为AD_VP或AD_PRES的记录可以在FILTER括号内使用OR逻辑运算符MAP pdb1.hr.employees, TARGET orclpdb.user1.employees, FILTER (STRFIND(job_id, AD_VP) 0 OR STRFIND(job_id, AD_PRES) 0);STRFIND函数返回指定字符串在字段中的位置索引如果未找到则返回0。因此大于0的判断即表示字段包含该子串。需要注意在FILTER中使用字符串必须加双引号这与WHERE中使用单引号有所不同。2.2 基于CSN的断点续传过滤在OGG运维中通过指定CSN启动复制进程是处理数据重同步的常见操作。传统方法是在START REPLICAT命令中指定CSN参数但有时会遇到该方式无法生效的情况。此时可在Replicat参数文件中使用FILTER结合GETENV函数来实现相同的效果MAP BLS.ESTRAINTS, TARGET ATM.RESTRAINTS, FILTER (GETENV(TRANSACTION, CSN) 12509724757269);GETENV函数可以获取当前事务的系统变更号通过与指定的CSN值比较Replicat进程将只处理CSN大于该值的事务从而实现从指定断点继续复制。这种方法在某些场景下更加稳定可靠。根据Oracle官方文档GETENV还可以获取GGHEADER中的操作类型信息例如可以通过GETENV(GGHEADER, OPTYPE) INSERT来判断当前是否为插入操作。2.3 工作负载拆分RANGE函数用于将数据按指定列哈希值均匀分布到多个Replicat进程中实现并行复制。RANGE的工作原理是计算指定列或主键列的哈希值将哈希值与总范围数取模与当前进程的归属范围进行比较决定记录是否属于该进程。使用RANGE的典型场景是当一张大表需要并行复制时通过多个Replicat进程分别处理不同范围的数据。以下示例演示了按ORDERID列将数据拆分到两个Replicat进程中处理第一个Replicat进程配置MAP $PRODSRC.PRODMSTR.ORDMASTR, TARGET $PROD.MASTER.ORDMASTR, FILTER (RANGE (1, 2, ORDERID)); MAP $PRODSRC.PRODMSTR.ORDDETL, TARGET $PROD.MASTER.ORDDETL, FILTER (RANGE (1, 2, ORDERID));第二个Replicat进程配置MAP $PRODSRC.PRODMSTR.ORDMASTR, TARGET $PROD.MASTER.ORDDETL, FILTER (RANGE (2, 2, ORDERID)); MAP $PRODSRC.PRODMSTR.ORDDETL, TARGET $PROD.MASTER.ORDDETL, FILTER (RANGE (2, 2, ORDERID));RANGE函数基于指定列计算哈希值并取模确保相同的键值始终路由到同一个Replicat进程从而保证数据一致性和事务完整性。如果未指定列则使用表的主键列进行计算。在多表关联同步的场景中使用相同的列作为RANGE参数可以保持表间关联数据的完整性ORDERID在ORDMASTR和ORDDETL中同时使用保证了主从表数据的一致性。Oracle官方文档也指出RANGE函数在FILTER中的使用提供了不同于FILE或MAP的RANGE选项的能力例如支持指定列。2.4 基于操作类型的过滤FILTER支持针对特定SQL操作类型进行过滤这是WHERE不具备的能力。通过ON INSERT、ON UPDATE、ON DELETE选项可以精确控制FILTER在何种操作下生效。例如仅在UPDATE操作时过滤数据量超过50条的记录TABLE ACT.TCUSTORD, FILTER (ON UPDATE, AMOUNT 50);还可以组合ON INSERT和ON DELETE选项TABLE ACT.TCUSTORD, FILTER (ON INSERT, ON DELETE, AMOUNT 50);除了ON选项FILTER还支持IGNORE INSERT、IGNORE UPDATE、IGNORE DELETE选项用于在特定操作类型上忽略过滤条件。2.5 多条件组合过滤当需要同时满足多个过滤条件时可以使用AND和OR进行逻辑组合。以下示例筛选金额大于10000且字段存在的记录WHERE (AMOUNT PRESENT AND AMOUNT 10000)PRESENT用于判断字段是否存在于记录中这在处理压缩更新记录时尤其重要。当压缩更新记录中缺少过滤所需的字段时OGG会将该记录丢弃并输出到废弃文件中并发出警告。先判断字段存在再判断字段值是处理压缩更新场景的推荐做法。NULL测试可以评估SQL列是否为NULL值。以下测试在列出现且不为NULL时返回TRUEWHERE (AMOUNT PRESENT AND AMOUNT NULL)FILTER还支持使用BEFORE函数在UPDATE操作中比较字段更新前的值。在以下示例中FILTER确保源端UPDATE操作中COUNT列的旧值与目标端当前值匹配FILTER (ON UPDATE, BEFORE (COUNT) CHECK.COUNT)三、配置中的注意事项3.1 列的可用性FILTER只能对OGG可用的列进行操作。在Extract端OGG可以访问重做日志和数据库中的所有列。但在Replicat端列必须存在于trail文件中。因此任何需要在Replicat端FILTER中使用的列都必须通过ADD TRANDATA COLS显式添加补充日志并保留LOGALLSUPCOLS的默认设置。如果过滤所需的列不在trail文件中FILTER条件将无法正确执行。在协调复制模式下使用THREADRANGE时也是如此指定的列必须存在于trail文件中可以通过KEYCOLS或FETCHCOLS控制。3.2 压缩更新的处理在压缩更新记录场景下只有记录中实际发生变更的列才会被写入trail未变更的列在记录中缺失。当使用压缩更新时FILTER条件中涉及的列可能缺失导致记录被错误丢弃。Oracle官方文档建议优先使用主键列进行过滤因为键字段始终存在于压缩记录中。如果必须使用非主键列应先使用PRESENT判断列是否存在再进行值比较避免因列缺失导致的意外丢弃。以下示例正确处理了压缩更新场景WHERE (AMOUNT PRESENT AND AMOUNT 10000)这个条件在AMOUNT字段缺失时不会丢弃记录只在AMOUNT存在且大于10000时才返回TRUE。3.3 建议的过滤层级根据性能最佳实践数据过滤应尽可能在靠近数据源的位置完成。如果在Extract端进行过滤网络传输的只有满足条件的记录网络负载最低。如果在数据泵中过滤源端到数据泵的传输仍包含未过滤数据。在Replicat端过滤会在网络中传输所有数据然后由Replicat进程丢弃不需要的记录。Oracle官方文档建议当需要进行大量过滤和转换时建议使用一个或多个数据泵来处理这部分工作。可以将过滤和转换工作拆分到数据泵和Replicat两端以平衡负载。对于初始化场景SQLPREDICATE是比WHERE或FILTER更好的选择。因为它直接作用于SQL语句告诉OGG只取需要的部分而非取所有数据之后再过滤。3.4 多条件组合的语法当FILTER条件中存在多个表达式时需要使用括号进行逻辑分组确保运算顺序清晰。多个FILTER条件可以使用AND或OR连接例如FILTER (STRFIND(job_id, AD_VP) 0 OR STRFIND(job_id, AD_PRES) 0)需要注意的是不能在MAP语句中写多个独立的FILTER子句所有过滤条件必须在一个FILTER中通过逻辑运算符组合。不过TABLE或MAP语句可以包含多个FILTER子句OGG会按照顺序执行这些过滤器直到有一个失败或全部通过。如果一个过滤器失败则全部失败。FILTER还可以与SQLEXEC结合使用。SQLEXEC可以在Extract或Replicat中用于执行SQL语句、存储过程或SQL函数执行结果可以在FILTER条件中使用。例如在执行更新操作时进行查询将查询结果用于FILTER条件判断。四、常见错误排查4.1 OGG-00375 Error in FILTER clause这个错误通常表示FILTER语法不正确。常见原因包括使用了WHERE但不支持LIKE模糊查询却尝试使用LIKE语法。解决方案是改用FILTER结合STRFIND函数。FILTER括号内的表达式不完整例如缺少右括号或逻辑运算符。使用了FILTER但不支持该版本OGG的函数名称。检查函数名是否正确例如STRFIND的写法。FILTER中使用字符串未加双引号。4.2 OGG-00446 invalid column name当FILTER条件引用的列不存在于trail文件中时会报此错误。可能原因是该列未在Extract端通过ADD TRANDATA COLS添加补充日志或列名拼写错误。解决方案是检查列名是否正确确认补充日志配置是否完整。4.3 过滤无效如果FILTER条件在Extract端配置后没有生效可能原因是过滤所需的列未启用补充日志导致trail中没有该列信息。需要检查ADD TRANDATA COLS的配置是否正确。另外确认在Extract、数据泵和Replicat三端的配置是否过于分散。当Extract端过滤已配置时后续的数据泵和Replicat可以不再重复配置否则可能因语法冲突导致进程异常。4.4 压缩更新导致的意外丢弃如果遇到记录被意外丢弃的情况检查是否涉及压缩更新场景。解决方案是在FILTER或WHERE条件中添加PRESENT检查确保只在字段存在时才进行比较。如果需要精确控制处理行为可以配置REPERROR来处理错误场景。五、最佳实践总结5.1 过滤位置的选择策略对于数据过滤建议按照以下原则选择过滤位置初始化场景使用SQLPREDICATE直接在SQL中过滤需要减少网络传输时在Extract端过滤需要减轻源端压力但接受部分网络传输时在数据泵端过滤仅需在目标端实现精细分发时在Replicat端过滤。5.2 FILTER vs WHERE的选择矩阵场景推荐方案原因简单等值比较WHERE性能更优语法简洁模糊匹配FILTER STRFINDWHERE不支持LIKE哈希范围拆分FILTER RANGEWHERE不支持函数CSN断点续传FILTER GETENVWHERE不支持函数操作类型过滤FILTERWHERE不支持ON选项5.3 性能优化建议对于大规模过滤场景建议在Extract端进行过滤以减少trail文件大小和网络传输。当使用RANGE拆分负载时优先在Extract端进行。根据源端和目标端能力合理分配过滤职责。当需要大量过滤和转换时使用数据泵分担工作。结语OGG的FILTER功能为Replicat进程提供了灵活的行级数据过滤能力。通过STRFIND实现模糊匹配、RANGE实现并行复制拆分、GETENV实现基于CSN的断点续传这些功能覆盖了绝大多数生产场景下的数据过滤需求。在实际配置中理解FILTER与WHERE的差异、确保过滤列的可用性、合理选择过滤层级是成功应用的关键。当遇到过滤失败时优先检查列的可用性、语法正确性、以及补充日志的配置这些步骤能够解决绝大部分问题。Oracle官方文档也指出配置错误的过滤和转换是常见的故障来源。因此建议在生产环境应用前先在测试环境中验证FILTER条件的效果并通过discard文件监控被过滤的数据量。善用REPERROR结合FILTER的RAISEERROR选项可以为过滤失败场景建立完善的监控和异常处理机制。
返回列表