以下為您介紹即時整合相關的常見問題和解決方案。
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即時整合。即時整合在部分巨量資料量的情境下,效能表現良好。具體原理如下:
擷取每次讀取的
startScn和endScn。找出包含
startScn的所有的archiveLog和onlineLog檔案(>=startScn都會載入)。調用
Oracle LogMiner分析這些檔案,使用DBMS_LOGMNR.START_LOGMNR進行分析(這個步驟很慢)。從
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');