Oracle 高级复制配置步骤详细说明.docx
《Oracle 高级复制配置步骤详细说明.docx》由会员分享,可在线阅读,更多相关《Oracle 高级复制配置步骤详细说明.docx(13页珍藏版)》请在冰豆网上搜索。
![Oracle 高级复制配置步骤详细说明.docx](https://file1.bdocx.com/fileroot1/2023-3/2/10bfb0db-c6b7-49ed-80ca-4860e7724684/10bfb0db-c6b7-49ed-80ca-4860e77246841.gif)
Oracle高级复制配置步骤详细说明
Oracle高级复制配置步骤详细说明
首先,数据库要具备高级复制功能(用system身份登录数据库,查看v$option视图,如果其中Advancedreplication为TRUE,则支持高级复制功能;否则不支持)
一.数据库基本情况
数据库A 版本oracle10.2.0.3数据库名sid:
shenzhen
数据库B 版本oracle10.2.0.3数据库名sid:
beijing
主体定义站点:
Ashenzhen主体站点:
Bshenzhen注:
主体定义站点指配置复制工作的站点
本例涉及的用户.复制管理员:
repadmin应用用户:
cqm本例复制的对象:
reptest数据表本例的先决条件:
你需要设置好相应的参数,job_queue_processes需要大于0,global_name=true,并且建立相应的dblink.
altersystemsetglobal_names=truescope=both;
二.在两个数据库上分别创建应用用户CQM
CREATEUSERCQMIDENTIFIEDBYCQMDEFAULTTABLESPACEusersTEMPORARYTABLESPACETEMP;
GRANTDBATOCQM;
三.在两个数据库上分别创建复制管事员用户REPADMIN
--创建repadmin用户管理复制环境
CREATEUSERREPADMINIDENTIFIEDBYREPADMIN;
ALTERUSERREPADMINDEFAULTTABLESPACEUSERS;
ALTERUSERREPADMINTEMPORARYTABLESPACETEMP;
GRANTconnect,resourceTOREPADMIN;
--授予repadmin用户权限可以管理当前站点中任何主体组
EXECUTEdbms_repcat_admin.grant_admin_any_schema('REPADMIN');
--授予repadmin用户权限可以为任何表创建snapshotlogs
GRANTcommentanytableTOREPADMIN;
GRANTlockanytableTOREPADMIN;
--指定repadmin用户为propagator,并授予执行任何procedure的权限
EXECUTEdbms_defer_sys.register_propagator('REPADMIN');
GRANTexecuteanyprocedureTOREPADMIN;
四.更改两个数据库的全局名称
alterdatabaserenameglobal_nametobeijing.TEST.COM.CN;
alterdatabaserenameglobal_nametoshenzhen.TEST.COM.CN;
五.在两个数据库上建立数据库链接
createpublicdatabaselinkbeijing.TEST.COM.CNconnecttoREPADMINidentifiedbyREPADMINusing'beijing';
createpublicdatabaselinkshenzhen.TEST.COM.CNconnecttoREPADMINidentifiedbyREPADMINusing'shenzhen';
六.在两个数据库的应用用户CQM下创建表
在数据库shenzhen上用户CQM下:
注意,要进行复制的表必须有主键
CREATETABLETEST(IDNUMBER(10),TIMESTAMPDATEDEFAULTsysdate);
ALTERTABLETESTADD(CONSTRAINTTEST_PKPRIMARYKEY(ID));
在数据库beijing上用户CQM下:
CREATETABLETEST(IDNUMBER(10),TIMESTAMPDATEDEFAULTsysdate);
ALTERTABLETESTADD(CONSTRAINTTEST_PKPRIMARYKEY(ID));
七.在主体定义站点开始操作(数据库A:
shenzhen)
以REPADMIN登录数据库shenzhen
创建复制组:
executedbms_repcat.create_master_repgroup('rep_hh');[多余的]
executedbms_repcat.create_master_repgroup('repg');
在复制组里加入复制对象:
executedbms_repcat.create_master_repobject(sname=>'cqm',oname=>'test',type=>'table',use_existing_object=>true,gname=>'repg',copy_rows=>false);
对复制对象产生复制支持:
executedbms_repcat.generate_replication_support('cqm','test','table');
executedbms_repcat.drop_master_repobject('scott','dept','table');[取消同步]
添加主体复制节点:
executedbms_repcat.add_master_database(gname=>'repg',master=>'',use_existing_objects=>true,copy_rows=>false,propagation_mode=>'asynchronous');
********************************************** 参数说明:
gname主复制组名 master加入主复制节点的另一个数据库 use_existing_objecttrue表示用主复制节点已经存在的数据库对象 copy_rowsfalse表示第一次开始复制时不用和主复制节点保持一致 propagation_mode同步地执行synchronous(上边配置异步复制) ***********************************************
在主体定义站点启动复制:
executedbms_repcat.resume_master_activity('repg',true);
executedbms_repcat.resume_master_activity('repg',false);
executedbms_repcat.suspend_master_activity('repg')[停止复制]
八.至此配置完成
附:
使用异步复制要运行以下的过程!
execdbms_defer_sys.schedule_push(destination=>'',interval=>'sysdate+1/1440',next_date=>sysdate);
execdbms_defer_sys.schedule_purge(next_date=>sysdate,interval=>'sysdate+1/1440',delay_seconds=>0,rollback_segment=>'');
***********************************************
execdbms_defer_sys.schedule_push(destination=>'',interval=>'sysdate+1/1440',next_date=>sysdate);
execdbms_defer_sys.schedule_purge(next_date=>sysdate,interval=>'sysdate+1/1440',delay_seconds=>0,rollback_segment=>'');
这种配置方式对网络的影响比较小!
管理也比较简单
1)模拟小数据量测试:
OK
2)模拟大数据量测试:
OK
CREATEORREPLACEprocedureinsert_into_test
as
inumber;
mNUMBER;
nNUMBER;
BEGIN
n:
=0;
FORiIN1..10000LOOP
m:
=i;
INSERTINTOtest(id)VALUES(m);
n:
=n+1;
IFn=1000THEN
COMMIT;
n:
=0;
ENDIF;
ENDLOOP;
COMMIT;
END;
添加复制对象的四个步骤!
executedbms_repcat.suspend_master_activity('repg')
executedbms_repcat.create_master_repobject(sname=>'cqm',oname=>'test1',type=>'table',use_existing_object=>true,gname=>'repg',copy_rows=>false);
executedbms_repcat.generate_replication_support('cqm','test1','table');
executedbms_repcat.resume_master_activity('repg',false)
executedbms_repcat.resume_master_activity('repg',true)
附:
做完的时候开始插入数据有问题
SQL>insertintotest(id)values
(1);
insertintotest(id)values
(1)
*
ERRORatline1:
ORA-04067:
notexecuted,storedprocedure"CQM.TEST$RP"doesnotexist
ORA-01085:
precedingerrorsindeferredrpcto"CQM.TEST$RP.REP_INSERT"
ORA-02063:
preceding2linesfromBEIJING
后来就可以拉
1,创建前数据要统一
2,运行executedbms_repcat.suspend_master_activity('repg')后源数据库的表不可以再进行数据的插入!
3,Job可以停到并不影响数据的复制(表怀疑与搞笑)
4,现在是同样的操作系统同样的数据库版本
5,以上是在同一操作系统下测试AIX5207
6,高级复制如果目的站点有问题或者网络有问题!
源站点的数据操作将会出错!
7,如果数据不同步的情况下,对源站点的数据操作会产生ORA-01403:
nodatafound的问题!
8,以上是数据的传输方式为同步的,如果修改成异步的传输方式上边的问题将不会出现的!
9,不可以使用truncatetable清理数据
常用问题解答:
Q:
如何计算延迟事务将占用多少的资源?
A:
DeferredTransactions
Oracleforwardsdatareplicationinformationbypropagating(thatis,sendingandexecuting)theRPCsthataregeneratedbytheinternaltriggersdescribedpreviously.TheseRPCsarestoredinthedeferredtransactionqueue.Inadditiontocontainingtheexecutioncommandfortheinternalprocedureatthedestinationsite,eachRPCalsocontainsthedatatobereplicatedtothetargetsite.Oracleusesdistributedtransactionprotocolstoprotectglobaldatabaseintegrityautomaticallyandensuredatasurvivability.
DeferredTransactionQueue
Thisqueuestoresthetransactions(forexample,DML)thatareboundforanotherdestinationinthemastergroup.OraclestoresRPCsproducedbytheinternaltriggersinthedeferredtransactionqueueofasiteforlaterpropagation.OraclealsorecordsinformationaboutinitiatingtransactionssothatallRPCsfromatransactioncanbepropagatedandappliedremotelyasatransaction.Oracle'sreplicationfacilityimplementsthedeferredtransactionqueueusingOracle'sadvancedqueuingmechanism.上面是Oracle联机文档中对于延迟事务和延迟事务队列的描述。
开始的时候一直以为延迟事务应该是存在Oracle的一个内存结构中,所以总是担心如果复制环境中的网络长时间出现问题,那么会不会导致延迟事务队列占用大量的内存而使数据库的其它操作变慢,或者说超出了延迟事务可以使用的内存大小而产生错误。
因为上面提到延迟事务队列使用的是Oracle的高级队列(AdvancedQueue)算法,所以又查找了高级队列的文档,发现多处提到Table这个词,所以忽然明白所谓延迟事务的队列应该是存储在磁盘上的某些表中,这样陡然就解决了心中很多疑问,首先事务多只是占用硬盘空间,其次要想计算事务占用的资源可以通过表的block数来计算。
于是通过SQLTrace,找到了延迟事务相关视图的基表。
deftran对应DEF$_AQCALL表,通过执行计划也发现在统计大量延迟事务总数时候速度极为缓慢的原因,因为在作TABLEACCESSFULLDEF$_AQCALL,同时还会作TABLEACCESSFULLDEF$_AQERROR,还有UNIONALL的操作。
deferror对应DEF$_ERROR表。
defcall对应的也是DEF$_AQCALL和DEF$_AQERROR表。
现在我们检查一下DEF$_AQCALL表的信息。
SQL>;colownerfora10
SQL>;colobject_namefora20
SQL>;selectowner,object_name,object_id,data_object_id,object_typefromdba_objectswhereobject_name='DEF$_AQCALL';
OWNEROBJECT_NAMEOBJECT_IDDATA_OBJECT_IDOBJECT_TYPE
------------------------------------------------------------------------
SYSDEF$_AQCALL3913SYNONYM
SYSTEMDEF$_AQCALL38613861TABLE
SYSTEMDEF$_AQCALL3869QUEUE
Executedin0.06seconds从上面的结果可以看到这个表是属于SYSTEM的,在SYS下有一个同义词。
再检查一下segment的情况,我们可以从dba_segments或者dba_extents视图中查看。
SQL>;coltablespace_namefora20
SQL>;selectowner,tablespace_name,bytes,blocksfromdba_segmentswheresegment_name='DEF$_AQCALL';
OWNERTABLESPACE_NAMEBYTESBLOCKS
--------------------------------------------------
SYSTEMSYSTEM655368
Executedin0.11seconds由此我们已经可以知道作为高级复制中延迟事务存储所占用的资源,同时由于这是普通的表,那么当插入记录的时候当然也是会缓存在buffercache中。
这里不作讨论。
也不再讨论DEF$_AQERROR表,因为只有在延迟事务产生错误时才会插入,如果高级复制环境中没有太多错误,这个表的资源占用可以不考虑。
为了继续验证,现在测试环境中有REP_HOME复制组,其中的复制对象是SCOTT.EMP_2003表。
断开网络连接的情况下,我们插入10000条记录。
再次检索DEF$_AQCALL表现在的情况。
SQL>;selectowner,tablespace_name,bytes,blocksfromdba_segmentswheresegment_name='DEF$_AQCALL';
OWNERTABLESPACE_NAMEBYTESBLOCKS
--------------------------------------------------
SYSTEMSYSTEM2097152256
Executedin0.08seconds现在该表的大小已经扩大到2M,可以认为所有的复制数据和队列信息都存储在这张表中。
SQL>;selectcount(*)fromDEF$_AQCALL;
COUNT(*)
----------
10000
Executedin0.04seconds再次证明确实是10000条数据。
如果此时我们用repadmin用户检索defcall和deftran视图
SQL>;selectcount(*)fromdefcall;
COUNT(*)
----------
10000已用时间:
00:
00:
02.04
SQL>;selectcount(*)fromdeftran;
COUNT(*)
----------
1已用时间:
00:
00:
00.00可以看到deftran视图中只有一条记录,因为上面的10000条数据的插入是一个事务中完成的,所以在复制环境中作为一个延迟事务处理。
而defcall中则是10000条记录,详细查看内容,知道所有的cal事务号都相同,而callno不同,同时我们发现直接检索DEF$_AQCALL只需要0.04秒,而检索defcall视图却需要2秒,所以如果想要计算到底有多少数据需要处理的时候,我们可以直接从DEF$_AQCALL检索,这样可以缩短查询时间。
Q:
如果一张表没有主键,又确实需要复制,怎么办?
A:
不建议在高级复制的环境中出现这样的情况,应该确保每张表都有主键。
如果确实存在这种情况,那么需要用DBMS_REPCAT.SET_COLUMNS来生成代用主键。
executeDBMS_REPCAT.SET_COLUMNS(sname=>;test',oname=>;'tabel',column_list=>;'col1,col2,col3,col4');其中column_list是用逗号隔开的字段列表,不能有空格。
注意:
不要在执行set_columns之前生成对于没有主键的对象的复制支持,也就是不要运行generate_replication_support,否则会导致all_repobject视图中该对象状态变为ERROR,而无法再次set_columns。
如果误运行了复制支持而又没有成功,那么需要删除掉这个复制对象再重新生成。
也就是在对没有主键的表生成复制的时候,必须遵循以下顺序:
create_master_repobject->;set_columns->;generate_replication_support
Q:
高级复制环境中出现长时间的网络问题会出现什么情况?
A:
由于高级复制的传播都是通过JOB来实现的,而大家知道Oracle对于JOB的执行有个限制,就是如果一个JOB执行失败了16次,那么这个JOB将会被标志为BROKEN,以后这个JOB再也不会被自动执行,除非是手动设置BROKEN为FALSE或者手动成功地运行一次JOB。
这个特性给我们的实际应用中带来了一些麻烦,假设我们的PUSHJOB定义的时间间隔是一分钟,那么如果主体站点之间的网络出现长时间的问题,比如说超过了16分钟,也就是此时JOB已经失败了16次,那么PUSH的JOB就被标志为BROKEN了,这样等到网络问题修复,会发现堆积的延迟事务也不会被PUSH到其它的主体站点上。
如果不注意这个问题,往往就会出现严重的问题。
解决方案是另外作一个JOB,这个JOB里面每隔一定时间自动检查那个PUSHJOB的状态,如果是BROKEN的,那么自动将其BROKEN状态重新设置为FALSE,这样下次又可以重新执行了。
这个JOB中执行的存储过程基本上如下:
DECLARE
CURSORmy_broken_jobsIS
SELECTjobFROMuser_jobsWHEREbroken='Y';
BEGIN
FORbroken_jobINmy_broken_jobsLOOP
BEGIN
dbms_job.broken(broken_job.job,FALSE);
EXCEPTION
WHENOTHERSTHEN
NULL;
END;
ENDLOOP;
END;
Q:
如果高级复制环境中的主体定义站点损坏,如何将主体定义站点切换到另外的主体站点上?
A:
分为两种情况。
备注:
每次运行完repcat包以后都应该执行一次commit,因为某些rep的存储过程是不会自动commit的,同时这也是一个troubleshooting,一般的rep脚本都会较快的返回结果,如果一条命令之后长时间没有结果返回,那么很可能是上面的命令没有commit,取消掉当前的命令,然后作一次commit,再重新执行,一般都能够解决问题。
一是只有主体定义站点损坏。
假设站点A是主体定义站点,已经损坏,在复制环境中还有站点B,想作为新的主体定义