前段时间一致在做oracle高级复制,下面是在维护过程中对出现问题的一些分析、解决,贴出来希望对大家有帮助:
高级复制是oracle数据库的高级功能,它的维护比普通数据库复杂,下面是在已有高级复制数据库维护过程中出现过一些问题和解决办法。
1、稳定的物理链路:连接服务器的网络由于故障断开,服务器彼此之间数据就不能访问,数据无法传输;网络不稳定,数据就会发生丢包,不完整。
2、传输速度方面要求较高:否则还不如单级版本。
3、参与的服务器不能长期不开机:这样会积压大量的延迟任务,导致数据无法进行发布。
4、参与复制的表,不能在它上面直接执行任何DDL语句:因为ORACLE自动在参与复制的表上建立了内部的支持复制的TRIGGER和PACKAGE,在它上面直接执行任何DDL语句都会破坏这些复制支持。应该先SUSPEND要修改表所在的复制组,在REPICATION MANAGER中或调用REPCAT API执行DDL语句,然后重新GENERATE该表的复制支持,最后将复制组状态恢复为NORMAL。注意修改表结构的DDL语句中表名前一定要带上属主,并且最后没有分号。如果不小心直接执行了DDL语句,应该将该表移出复制环境,删掉,重新建立或从其它节点复制过来。
5、修改一张表加一个字段,并设置缺省值,如 ALTER TABLE OWNER.TABLE_NAME ADD(FIELD_NAME VARCHAR2(20) DEFAULT 'AAA');在9i之前不能一次执行,要分成两部分执行:
1、ALTER TABLE OWNER.TABLE_NAME ADD FIELD_NAME
2、ALTER TABLE OWNER.TABLE_NAME MODIFY FIELD_NAME DEFAULT 'AAA'
这是因为执行任何DDL语句,需要SUSPEND复制组,此时复制表只能查询,不能执行其它DML语句。如果直接加上一个字段同时赋予缺省值,此时的处理是加上一个字段,并立刻给该字段赋上给定的缺省值,这后面的DML语句是不能执行的,所以会报错。而分成两部分执行,第一部分先加一个字段,第二部分再修改该字段的定义,不会发生插入缺省值的DML操作,因此可以执行。
6、执行任何ADMIN REQUEST(对复制环境的管理命令)前,都要保证此时没有堆积的DEFERRED TRANS。
7、执行任何ADMIN REQUEST,必须一步一步执行。因为ADMIN REQUEST的工作原理,是用一个REPCATLOG表保存ADMIN REQUEST语句,执行完一条消失一条,后面的再继续执行。如果前面一条没执行完,后面的ADMIN REQUEST就无法执行,而REPCATLOG表如果不为空,复制组就无法恢复为NORMAL。因此每次发出ADMIN REQUEST后,都要检查REPCATLOG表,当所有节点上的REPCATLOG表都为空后,才能发出下一条命令。
8、如果发现REPCATLOG表中有无法执行的命令,可以重新APPLY或PURGE掉再重新发出命令执行。如果只是某一个节点上有遗留命令,可以在该节点上多APPLY几次执行。
9、如果发出命令后一直没有响应,而ADMIN REQUEST又无法PURGE掉,现象类似死锁。可以试着BROKEN掉该ADMIN REQUEST对应的JOB,重新刷新命令。如果命令能继续执行,恢复JOB的状态。如果还不行,从V$SESSION 和V$LOCK中查出死锁,用ALTER SYSTEM KILL SESSION 杀掉死锁的进程,如果还是杀不掉。就需要查出类型为'RQ'的分布式死锁,用SID再从V$PROCESS、V$BGPROCESS查出对应的后台进程,从操作系统级杀掉后台进程的方式来解锁,可能还需要重启数据库。最后再恢复JOB的状态和其他涉及的复制环境状态。
10、可以通过REPLICATION MANAGER或相关系统表查询复制环境情况,以REPADMIN用户登陆:
查看复制组和复制对象:
select gname,status from dba_repgroup;
--其中gname 即为复制组名,status 表示状态
select gname,oname,status from dba_repobject where type =’TABLE’ and oname =
‘table_name’;
--要查询某张表在哪个复制组中,将table_name 替换成表名,注意表名一定要大写。
查看分布式状态:
select job,what,next_sec,this_sec,last_sec,failures,broken from dba_jobs;
failures 小于16,broken 为N 表示分布式状态正常
查看数据库连接
select * from dba_db_links;
恢复传播复制任务
当连接复制环境中数据库的网络出现问题,可能会造成复制任务的停止。具体现象
表现为本地数据库的更新操作没有发布到远地数据库中。当出现这种情况时,请参考
前面提到的查看分布式状态的方法,检查复制任务是否正常。如果failures 大于等于16,
broken 为Y 表示分布式状态不正常,需要恢复传播复制任务。
exec dbms_job.run(jobno);
-- jobno 为在dba_jobs 表中ailures 大于等于16,broken 为Y 的job。
查看执行出错的事务
当分布式数据库出现不正常时,请执行下列语句,并根据查询的error_msg 来解决
问题。
select distinct origin_tran_db,destination,error_msg from deferror;
尝试执行出错的事务
根据查询的error_msg 解决了网络无法连接等问题后,请执行下列语句,并拷贝生
成的拼接exec 语句在客户端执行。
select ' exec dbms_defer_sys.execute_error ( ' ' ' || DEFERRED_TRAN_ID || ' ' ' , ' ' ' ||
DESTINATION || ' ' ' )' from deferror;
删除执行出错的事务
可能会遇到这样一种状况,尝试执行出错的事务,该事务依旧执行不成功。如果此
时deferror 表中的error_msg 都是“NO DATA FOUND”的错误,那么可以考虑删除执
行出错的事务。请特别注意,必须确认已经解决了出错原因,并在每个分布式节点都
尝试执行出错的事务后,才可以删除再次执行出错的事务,否则会造成分布式数据库
的数据不一致。
select ' exec dbms_defer_sys.delete_error ( ' ' ' || DEFERRED_TRAN_ID || ' ' ' , ' ' ' ||
DESTINATION || ' ' ' )' from deferror;