前言:
Oracle CDC是数据库自带的数据库数据复制和增量数据抽取工具,提供五种复制模式
1 Synchronous Change Data Capture Configuration(同步复制)
2 Asynchronous HotLog Configuration(异步在线日志CDC)
3 Asynchronous Distributed HotLog Configuration(异步分布式CDC)
4 Asynchronous Autolog Online Change Data Capture Configuration(异步在线日志复制CDC)
5 Asynchronous AutoLog Archive Change Data Capture Configuration(归档日志CDC)
本文主要讲述在日常运维CDC过程中遇到过6个问题以及解决方法,希望可以帮助到遇到相同问题的读者
问题一:ORA-26687: no instantiation SCN provided for ""." in source database ""
造成这个问题的主要原因通常为源端对表进行了DDL操作,表被drop或者重建,导致目标端的apply应用进程出现没用初始SCN的报错
解决该问题需要我们指定目标端表的初始SCN的方法
参考mos:DBA_APPLY_INSTANTIATED_OBJECTS and ORA-26687 (Doc ID 783815.1):
1 在源端通过表DBA_CAPTURE_PREPARED_TABLES查看当前表的SCN
SELECT TABLE_OWNER, TABLE_NAME, SCN
from DBA_CAPTURE_PREPARED_TABLES;
2 将步骤1查到的SCN,在目标端apply设置
BEGIN DBMS_APPLY_ADM.SET_TABLE_INSTANTIATION_SCN(
source_object_name=>'xxxxx',
source_database_name=>'xxxxx',
instantiation_SCN=>28359231312);
END;
/
3 重新手动执行发生错误的事务
--通过dba_apply_error表查询错误的local transaction id
exec DBMS_APPLY_ADM.EXECUTE_ERROR('localtransactionid')
4 重新启动源端apply进程
exec dbms_apply_adm.stop_apply('');
exec dbms_apply_adm.start_apply('');
问题二:源端捕获进程状态WAITING FOR REDO:FIRST SCN xxxxx,数据不同步
造成该问题的原因主要有1 捕获进程capture停止时间过长,导致所需要的归档日志被删除丢失 2 Bug 20532070导致,在12.1.0.2版本之前,重启源端捕获进程可能会发生WAITING FOR REDO:FIRST SCN xxxxx
解决该问题一个是可以通过恢复归档日志的方式进行,需要将FIRST SCN xxxxx之后的日志都进行恢复,可以通过查询 dba_registered_archived_log查看需要恢复的归档日志
另一个方法是,调整capture进程启动的first scn号为required_checkpoint_scn
参考:After Capture abort restart results in WAITING FOR DICTIONARY REDO: FIRST SCN instead of starting at the REQUIRED_CHECKPOINT_SCN (Doc ID 1487470.1
1 查看捕获进程需要的checkpoint_scn
select REQUIRED_CHECKPOINT_SCN from dba_capture;
2 修改捕获进程的first scn
exec dbms_capture_adm.stop_capture('CAPTURE')
BEGIN
DBMS_CAPTURE_ADM.ALTER_CAPTURE(
capture_name => 'CAPTURE',
first_scn => );
END;
/
exec dbms_capture_adm.start_capture('CAPTURE')
问题三:源端捕获进程为PAUSED FOR FLOW CONTROL,数据不同步或者同步缓慢
捕获进程此状态表示流量控制,用于在传播或应用落后不可用时减少捕获的LCR的溢出。捕获进程状态为PAUSED FOR FLOW CONTROL,则捕获进程无法将逻辑更改记录(LCR)排入队列,发送的原因可能是由于源端捕获或者目标端stream pool内存不足,propagation传播进程或者apply应用进程状态异常也可能是因为传播和应用进程消耗消息的速率低于捕获进程创建消息的速率。之前遇到过的主要还是stream pool内存不够导致的
修复该问题的方法
1 如果propagation传播进程或者apply应用进程状态为disabled,则需要enable启动进程
2 扩容stream pool内存池
3 进程性能缓慢问题,可以尝试删除传播并应用流程规则或简化规则条件
参考:https://docs.oracle.com/database/121/STRMS/strms_trcapture.htm#STRMS1032
1 检查propagation传播进程或者apply应用进程状态是否正常
--检查apply进程
Column PUBLISHER format a15
column change_set format a20
column apply_name format a25
column queue_name format a25
column ERROR_MESSAGE format a30
select PUBLISHER, s.SET_NAME change_set, a.APPLY_NAME, a.QUEUE_NAME, STATUS, ERROR_MESSAGE
from dba_apply a, change_sets s
where a.apply_name=s.apply_name
and a.queue_name = s.queue_name
and a.queue_owner = s.publisher;
--检查propagation传播进程
column "Source Queue" format a30
column "Dest Queue" format a35
column "Destination Name" format a35
select PROPAGATION_NAME, DESTINATION_DBLINK "Destination Name", SOURCE_QUEUE_OWNER||'.'||SOURCE_QUEUE_NAME "Source Queue",
DESTINATION_QUEUE_OWNER||'.'||DESTINATION_QUEUE_NAME "Dest Queue",
STATUS, ERROR_MESSAGE
from dba_propagation;
2 检查目标端是否有在正常接收以及应用
select * from V$STREAMS_APPLY_READER
select * from V$STREAMS_APPLY_SERVER
3 源端的缓冲区发布状态,确认捕获进程流量限制的原因
select PUBLISHER_STATE from V$BUFFERED_PUBLISHERS;
4 查看stream pool内存的使用
select name,bytes/1024/1024
from v$sgastat
where pool='streams pool'
order by 2;
像之前遇到过的由于目标端stream pool使用过高,导致的源端限流,后面通过扩容stream pool解决
问题四:目标端SYSAUX表空间暴增,产生大表STREAMS$_APPLY_SPILL_MSGS_PART
SYS.STREAMS$_APPLY_SPILL_MSGS_PART是应用进程的溢出表,当CDC捕获应用到大事务(即LCR数量超过TXN_LCR_spill_THRESHOLD的事务)或长时间运行的事务(超过10分钟未收到LCR的打开事务)才会溢出到应用溢出表。应用溢出表位于SYSAUX中,并使用分区表来存储LCR。每个事务都是表的一个单独分区(键是apply_name和事务id)。当应用了一个事务,并且该删除该事务的LCR时,将为transactionid执行丢弃分区。
造成该问题的主要原因为,CDC源端捕获了大事务,导致目标的的应用进程的事务产生了溢出
解决该问题主要有两种方式一种是临时扩容SYSAUX表空间,等目标端处理完大事务之后,再回收SYSAUX表空间
另一种方式是忽略该大事务,注意这会导致目标端数据丢失,操作方式如下
参考:SYSAUX Tablespace Grows Quite Fast Due to Apply Spilling (Doc ID 556183.1)
--源端查询
select streams_name "Streams Name",
streams_type "Streams Type",
xidusn||'.'||xidslt||'.'||xidsqn XID,
to_number (sysdate-last_message_time)*1440
"Time Since Last Message (min)"
from GV$STREAMS_TRANSACTION
where to_number (sysdate-last_message_time)*1440 >= 20
order by "Time Since Last Message (min)";
--目标端查询
SELECT * FROM DBA_APPLY_SPILL_TXN;
2 源端进程设置忽略该事务ID
exec dbms_capture_adm.stop_capture('CAPTURE_NETDB');
exec dbms_capture_adm.set_parameter('CAPTURE_NETDB','_ignore_transaction','3.30.13393');
exec dbms_capture_adm.start_capture('CAPTURE_NETDB');
3 目标端进程设置忽略该事务ID
exec dbms_apply_adm.stop_apply('APPLY_NETDB');
exec dbms_apply_adm.set_parameter('APPLY_NETDB','_ignore_transaction','3.30.13393');
exec dbms_apply_adm.start_apply('APPLY_NETDB');
4 目标端清理该事务的溢出信息
exec dbms_apply_adm.stop_apply('APPLY_NETDB');
execute dbms_apply_adm.set_parameter('APPLY_NETDB','_ignore_transaction','3.30.13393');
exec sys.purge_spill_txn('APPLY_NETDB','3.30.13393');
5 sys.purge_spill_txn函数
--该函数从Oracle mos上下载
create or replace procedure purge_spill_txn wrapped
a000000
1
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
7
7b1 40a
LjTu5SYzX5Y445YIWAJ/qtCS3Y8wgzvDTK6GfC80weQYlOby91EYwHo3MLi3eS1abuDagL6c
Fqk3/PIpbCa5yJKGIJAaT2f7KWjl8vxVgUeK2FtlM39aFBX1pyR1oHVK1Iag5Nrerd051qV7
lFbmDpVE5HAlJBebhcep/ulWfz2E95tw9pbdLyroLedkHjRIdgeFNm5uNdACniipPlt+uUSD
yEPToXfpQqO7JvsoaqAfwryDaLf0pYikfHAJsPKAI0IwCscwMGeoIrYtWnilloS8BePRM77K
GlVaYzhonFdattdqn42FEG+bT7SjQxJkxQmyW47zgQ1EDHp6VFtHAkofdO15e8vuKfpX4TI7
g/IMkfeDIBixOImP3T2tCQ+HUq0K/QtPeagb4QSbyszgIr8Fuc/clsV39pacrMDfq8mv6mi9
qdRNEGus1Sa6pChoYv1uw7wELhyph6meSHdYcmLhsdb4wXbCKfXk4evkOjyOArJVYNzIerqL
nEI3zJSz58P0k6owKKNM4vTD9gwhKErL41tzfceOM2hkfHzIVXrBY74KL7SGIF8BQzyO49vN
tJG2x1sDJvZiNsrMSQlQ7/EVNL9F/WgtRL/knd3wG2ki7Cr1G3KhBpqCgoK7r4wkKR7GzNsy
Yn3RNKRtxAMV9guxOb8NzFwNRuXXKM/9Jrzli8J/IACr9QnrKZ6tJZRLhzrwN+gTFdfUY/pr
R0jUORicUUyJvvpBGHOgZaOM7l4IaRrrVpavAgJUINHERxe3BdghcIyAQ31C4V4lvx0xwQU8
wwNvkoLFLGsWT5e2tMfqBIcDZrW7KtcdEUgOI+4vc0bbQ8xG+7AaeMITenaSV1B6bys4+38N
oeUNyRBYrDf4fiHiXdZMkvcdJtBcdUV0c1fdKDawNvz/o8vyiGJ9t6qI6lPKbKyDiG2hulTb
OqAIaT48gFyxErHPCpNSyog2KylMv7irwGN5oQKricl7zBfRx5CkgLSXT+ZxTAiY/CG3NI53
LcUQ+FtXd/Ni
/
6 清空源端的忽略事务配置
exec dbms_capture_adm.stop_capture('CAPTURE_NETDB');
exec dbms_capture_adm.set_parameter('CAPTURE_NETDB','_ignore_transaction',null);
exec dbms_capture_adm.start_capture('CAPTURE_NETDB');
7 清空目标端的忽略事务配置
exec dbms_apply_adm.stop_apply('APPLY_NETDB');
exec dbms_apply_adm.set_parameter('APPLY_NETDB','_ignore_transaction',null);
exec dbms_apply_adm.start_apply('APPLY_NETDB');
问题五:propagation传播进程报错Streams Enqueue Aborted Due to Low SGA
源端的propagation传播进程报错由于low SGA,造成该错误的原因通常为大事务导致的源端,目标端stream pool内存使用过高以及源端,目标端AQ_TM_PROCESSES参数设置为0导致
问题解决
参考:ORA-23603 'STREAMS enqueue aborted due to low SGA' Error from Streams Propagation, and V$STREAMS_CAPTURE.STATE Hanging on 'Enqueuing Message' (Doc ID 745601.1)
ORA-23603: Streams Enqueue Aborted Due to Low SGA (Doc ID 333068.1)
1 查看当前propagation传播进程状态
select PROPAGATION_NAME,ERROR_MESSAGE,ERROR_DATE from dba_propagation;
2 重启propagation传播进程,通常可以临时解决该问题,但报错可能后续还会再发生
exec dbms_propagation_adm.stop_propagation('STRMADMIN_PROPAGATE',true);
exec dbms_propagation_adm.start_propagation('STRMAMDIN_PROPAGATE');
3 检查当前AQ_TM_PROCESSES配置参数是否为0,建议配置为1
show parameter AQ_TM_PROCESSES
alter system set aq_tm_processes=1;
4 检查streams pool内存的使用率是否过高,如果使用率过高,可以对streams pool进行扩容
select name,bytes/1024/1024
from v$sgastat
where pool='streams pool'
order by 2;
5 应用避免大事务的发生,大事务会导致产生大量的LCR,导致streams pool使用上升以及LCR队列溢出
col QUEUE format a50 wrap
col "Message Count" format 99999999999 heading 'Current Number of|Outstanding|Messages|in Queue'
col "Spilled Msgs" format 99999999999 heading 'Current Number of|Spilled|Messages|in Queue'
col "Total Messages" format 99999999999 heading 'Cumulative |Number| of Messages|in Queue'
col "Total Spilled Msgs" format 99999999999 heading 'Cumulative Number|of Spilled|Messages|in Queue'
SELECT queue_schema||'.'||queue_name Queue, startup_time, num_msgs "Message Count", spill_msgs "Spilled Msgs", cnum_msgs "Total Messages", cspill_msgs "Total Spilled Msgs" FROM gv$buffered_queues;
问题六:propagation传播进程报错ORA-26851:unable to apply "",because it has connected to another capture,ORA-02063 preceding line from dblink
造成该问题的原因通常为源端capture进程发送了重启,而目标端apply的信息还没更新,导致产生了该报错
解决该问题只需要重启目标端apply进程即可
exec dbms_apply_adm.stop_apply('');
exec dbms_apply_adm.start_apply('');