背景
本文档提供了Dataphin平台Oracle CDC实时集成相关问题排查指南,覆盖了权限等常见问题,旨在帮助快速定位和解决Oracle数据库变更数据捕获(CDC)集成过程中所可能遇到的技术难题,确保数据的实时、准确同步。
版本说明
DataphinV3.13版本前实时集成的Oracle CDC版本是2.3,V3.13版本后实时集成的Oracle CDC版本是2.4
问题排查
权限问题
很多问题都是权限导致的,首先确保一定按照自己的数据库(CDB,容器数据库(Container Database)模式、非CDB模式)环境,配置好Oracle的配置。
参考:https://ververica.github.io/flink-cdc-connectors/release-2.4/content/connectors/Oracle CDC.html
对照参考一下debezium的文档:https://debezium.io/documentation/reference/1.9/connectors/oracle.html#oracle-connector-properties
说明:Oracle CDC的权限项目比较多,CDB模式和非CDB模式的权限有不同,请先按照文档配置。
查询用户的权限用如下命令:
-- 查询当前账户: select user from dual; SELECT * FROM DBA_SYS_PRIVS WHERE GRANTEE = 'C##DBZUSER'; SELECT TABLE_NAME FROM DBA_TAB_PRIVS WHERE GRANTEE = 'C##DBZUSER';
常见问题
- 任务运行报错:Oracle LogMiner 不支持在PDB,可插拔数据库(Pluggable Databases)上执行
原因:在CDB数据库中,读取PDB的补偿日志,需要额外配置参数:debezium.database.pdb.name
- 任务运行报错:
ORA-00942: table or view does not exist
,深层原因是:UPDATE LOG_MINING_FLUSH SET LAST_SCN =
原因:Oracle CDC 2.4的一个bug,参考:https://github.com/apache/flink-cdc/issues/3044。
方案:需要手动去CDB的数据库中,切换到CDB实例,把LOG_MINING_FLUSH重建一下。
-- 切换到CDB实例 ALTER SESSION SET CONTAINER = CDB$ROOT; -- 建表并写入数据 CREATE TABLE LOG_MINING_FLUSH(LAST_SCN NUMBER(19,0)); INSERT INTO LOG_MINING_FLUSH VALUES (0);
- 任务运行报错:表名长度超过30个字符(
Table 'xxx' won't be captured by Oracle LogMiner because its name exceeds 30 characters
)
原因:Oracle LogMiner 的限制,参考文档:https://docs.oracle.com/en/database/oracle/oracle-database/21/sutil/oracle-logminer-utility.html#GUID-7594F0D7-0ACD-46E6-BD61-2751136ECDB4
方案:目前只能绕过,对于需要采集的表,请限制表名和列名都<=30个字符。
- 运行日志报错:DataException: file is not a valid field name
原因:Oracle LogMiner日志中有数据的字段的名字是file,没有定义在Oracle LogMiner的表的schema中,导致找不到列,报错。
方案:保持Flink中字段的名字大小写和Oracle上的表完全一样
- 任务运行正常,看日志也读取到Oracle的Oracle LogMiner数据了,但是无法读取到数据。
原因:Oracle CDC的读取效率比较低。具体原理如下:
-- 每次读取都按照如下步骤操作 1. 获取每次读取的startScn和endScn 2. 找出包含startScn的所有的archiveLog和onlineLog文件(>=startScn都会加载) 3. 调用Oracle LogMiner分析这些文件,用DBMS_LOGMNR.START_LOGMNR分析 (这个步骤很慢) 4. 从V$LOGMNR_CONTENTS中读取分析后的cdc数据 (这个读取步骤也比较慢)
当数据量比较大的时候,会导致Oracle CDC读取的数据更慢(因为存在数据重复分析)。而且Oracle CDC使用了在线字典,会有额外的资源开销。
案例:Oracle CDC读取速率慢。原因是数据量比较大,endScn进度很慢,导致每次会用START_LOGMNR重复分析日志文件。最终越分析越慢。
这个是Oracle CDC的架构问题,无法解决。建议使用Dataphin实时集成。实时集成在部分大数据量的场景下,性能表现良好,已在某企业生产环境得到验证。
分析方法
常用命令:
-- 切换CDB和PDB ALTER SESSION SET CONTAINER = CDB$ROOT; -- 查询当前用户 select user from dual; -- 查询补偿日志是否开启 select * from dba_log_groups where table_name = 'PF_ID_NAME_PK'; -- 查询用户权限 SELECT * FROM DBA_SYS_PRIVS WHERE GRANTEE = 'C##DBZUSER'; SELECT TABLE_NAME FROM DBA_TAB_PRIVS WHERE GRANTEE = 'C##DBZUSER'; -- 获取当前scn SELECT CURRENT_SCN FROM V$DATABASE
补偿日志分析:
-- 分析补偿日志 BEGIN DBMS_LOGMNR.ADD_LOGFILE(LOGFILENAME => '/opt/oracle/product/19c/dbhome_1/dbs/arch1_83_1158061769.dbf', OPTIONS => DBMS_LOGMNR.NEW); DBMS_LOGMNR.ADD_LOGFILE(LOGFILENAME => '/opt/oracle/oradata/ORCLCDB/redo01.log', OPTIONS => DBMS_LOGMNR.ADD_FILE); DBMS_LOGMNR.START_LOGMNR(Options => DBMS_LOGMNR.DICT_FROM_ONLINE_CATALOG); END; -- 停止日志分析 exec DBMS_LOGMNR.END_LOGMNR(); -- 查询补偿日志内容,里面会有变更记录 SELECT SEG_NAME,TIMESTAMP,OPERATION FROM V$LOGMNR_CONTENTS WHERE SEG_NAME = 'PF_ID_NAME_PK' ORDER BY TIMESTAMP;
补偿日志文件名获取
-- 查看online log文件名 查看logfile文件名: SELECT V$LOGFILE.MEMBER NAME, V$LOG.THREAD# THREAD_NUMBER, V$LOG.SEQUENCE# SEQUENCE_NUMBER, V$LOG.FIRST_CHANGE# FIRST_CHANGE_NUMBER, LEAD(V$LOG.FIRST_CHANGE#, 1, 281474976710655) OVER (ORDER BY V$LOG.SEQUENCE#) NEXT_CHANGE_NUMBER, TO_CHAR(V$LOG.FIRST_TIME, 'YYYY-MM-DD HH24:MI:SS') FIRST_TIME, TO_CHAR(LEAD(V$LOG.FIRST_TIME, 1, NULL) OVER (ORDER BY V$LOG.SEQUENCE#), 'YYYY-MM-DD HH24:MI:SS') NEXT_TIME, 0 BLOCK_SIZE, V$LOG.BYTES BYTES, V$LOG.GROUP# GROUP_NUMBER, V$LOG.MEMBERS MEMBERS, V$LOG.ARCHIVED ARCHIVED, V$LOG.STATUS STATUS FROM V$LOG, V$LOGFILE WHERE (V$LOG.STATUS = 'CURRENT' OR V$LOG.STATUS = 'ACTIVE' OR V$LOG.STATUS = 'INACTIVE') AND V$LOG.GROUP# = V$LOGFILE.GROUP# AND V$LOG.THREAD# = 1 ORDER BY V$LOG.SEQUENCE#; ------------------查询archive log SELECT NAME, THREAD# THREAD_NUMBER, SEQUENCE# SEQUENCE_NUMBER, FIRST_CHANGE# FIRST_CHANGE_NUMBER, NEXT_CHANGE# NEXT_CHANGE_NUMBER, TO_CHAR(FIRST_TIME, 'YYYY-MM-DD HH24:MI:SS') FIRST_TIME, TO_CHAR(NEXT_TIME, 'YYYY-MM-DD HH24:MI:SS') NEXT_TIME, BLOCK_SIZE, BLOCKS, DEST_ID, RESETLOGS_ID, RESETLOGS_CHANGE# RESETLOGS_CHANGE_NUMBER, RESETLOGS_TIME, STATUS, CREATOR, REGISTRAR, APPLIED, FAL, DELETED FROM V$ARCHIVED_LOG WHERE NAME IS NOT NULL AND STATUS = 'A' AND DELETED = 'NO' AND ARCHIVED = 'YES' AND STANDBY_DEST = 'NO' -- AND THREAD# = 1 -- AND RESETLOGS_ID = 1158061769 AND FIRST_TIME <= TO_TIMESTAMP('2024-02-22 11:30:00', 'yyyy-MM-dd hh24:mi:ss') AND NEXT_TIME > TO_TIMESTAMP('2024-02-22 12:00:00', 'yyyy-MM-dd hh24:mi:ss');
总结
本文档提供了一套Oracle CDC集成问题排查框架,旨在帮助高效地识别和解决在Dataphin实时集成中可能遇到的问题。通过本文档的指导,帮助实现数据在Oracle数据库与Dataphin平台间的准确、实时同步。如有其他问题可联系@朱健 (平丰)@唐晓旭 (小续)