全部產品
Search
文件中心

Dataphin:即時整合Oracle CDC相關問題

更新時間:Jan 25, 2025

以下為您介紹即時整合相關的常見問題和解決方案。

Dataphin即時整合使用的Oracle CDC版本?

Dataphin V3.13版本前即時整合使用的Oracle CDC 2.3版本;Dataphin V3.13版本後即時整合使用的Oracle CDC 2.4版本。

任務運行報錯:Oracle LogMiner不支援在PDB,可插拔資料庫(Pluggable Databases)上執行?

在CDB資料庫中,讀取PDB的補償日誌,需要額外配置debezium.database.pdb.name參數。

任務運行報錯:ORA-00942: table or view does not exist。

Oracle CDC 2.4的一個bug。產生的底層原因是UPDATE LOG_MINING_FLUSH SET LAST_SCN =。更多資訊,請參見oracle-cdc cannot read oracle multitenant pdb binlog

您需要手動去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)

對於需要採集的表,請限制表名和列名都<=30個字元。主要原因為Oracle LogMiner的限制。更多資訊,請參見LogMiner Requirements

作業記錄報錯:DataException: file is not a valid field name。

您需要使Flink中欄位的名字大小寫和Oracle上的表完全一樣。Oracle LogMiner日誌中有資料的欄位的名字是file,沒有定義在Oracle LogMiner的表的schema中,導致找不到列而報錯。

日誌能讀取到Oracle的Oracle LogMiner資料,但是無法讀取到資料。

主要是因為Oracle CDC的架構問題而導致讀取效率比較低,建議使用Dataphin即時整合。即時整合在部分巨量資料量的情境下,效能表現良好。具體原理如下:

  1. 擷取每次讀取的startScnendScn

  2. 找出包含startScn的所有的archiveLogonlineLog檔案(>=startScn都會載入)。

  3. 調用Oracle LogMiner分析這些檔案,使用DBMS_LOGMNR.START_LOGMNR進行分析(這個步驟很慢)。

  4. V$LOGMNR_CONTENTS中讀取分析後的CDC資料(這個讀取步驟也比較慢)。

當資料量比較大的時候,會導致Oracle CDC讀取的資料更慢(因為存在資料重複分析)。而且Oracle CDC使用了線上字典,會有額外的資源開銷。

附錄:問題排查

排查方法

當以上常見問題無法解決時,您可以通過以下方法進行排查。

Oracle CDC很多問題都是許可權導致的,首先確保一定按照自己的資料庫(CDB容器資料庫(Container Database)模式、非CDB模式)環境,配置好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';

排查命令

常用命令

-- 切換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');