Stream技术总结及11gR2 Stream Replication同步复制实验(SCHEMA&TABLE)

一、Stream技术特点及与OGG产品的主要区别


Stream和OGG都可作为高可用环境中用于复制并同步数据的解决方案。Stream是自9i以来,Oralce数据库提供的一种功能,主要是Oracle的消息队列(也叫Oracle Advanced Queue)技术的一种扩展应用,流复制(Stream replication)只是基于它的一个数据共享技术。不同的是,OGG作为原来的第三方软件,自从被oracle收购并加以改进以后,其功能上较Stream而言则更加完善,配置也更方便。它们都可以用于Oralce与Oralce或Oracle与非Oracle数据库之间的同步,但在复制机制上,还是存在不少区别的,主要有以下几点:

 

1.Stream由于是基于消息队列的,所以在同步复制数据库前,源和目标端必须都要配置一个队列Queue,再配置相关的capture,propagation,apply进程,并且还需要配置DB LINK,而OGG只需要配置extract,pump,replicat就可以满足复制条件。

 

2.Stream采用的是内部进程,即采用Oralce数据库提供的包和存储过程来配置进程,而OGG是需要另外安装软件,由软件来提供的参数命令来配置相关工作进程。

 

3.Stream采用的复制机制是类似与在DG中LOGICALSTANDBY的方式,即利用LOGMINER,对复制到目标端的log日志数据文件进行挖掘分析,然后重新执行SQL语句来达到同步数据的目的,使用的是自己特有的一种格式——LCR。Stream需要把日志文件全部通过队列复制到目标端,而不管是否是提交的数据,最后再过滤掉未提交的数据,应用提交数据,由于捕获的日志非常多(可能是大量无效数据,实时同步时,如果全部取消提交的话),对源端数据库会造成一定的影响,且有较高的网络依赖性,效率不高。而ogg则是采用自己的方式,通过抽取源端日志中已提交的事务,传送到目标端后直接应用,由于抽取的数据量较之Stream要少很多,所以效率要高,据官方称,理论上可以达到亚秒级别。

 

4.Stream由于是把Commited和Uncommited的数据都复制到源端,应用的时候只能采用SCN的顺序,而OGG因为复制的都是Commited的数据,在目标端也是以Commit的顺序应用的。这是它们之间在数据应用时的一大区别。

 

5.Stream作为数据库组件之一,其工作时需要用到数据库SGA分配的内存,还要建立StreamPool,占用了一定的数据库资源,而OGG由于是第三方软件,用的是OS分配的内存,对数据库的影响很有限。

 

6.最后一点区别和机制无关,但是也得提一下,鉴于ogg动辄百万的昂贵的价格,如果只是执行复制Schema或Table等简单操作,Stream完全可以胜任,在能够以不花钱又能完成相同的任务的前提下,首选的当然是简单又好用的Stream了。由于这两种软件在所实现的功能上差异性并不大,考虑到商业因素,将来Oralce一定是大力发展OGG,据我所知,目前Oralce已经停止对Stream的更新了。

 

Stream用于Oralce数据库之间的数据复制,包括database,schema,table,数据仓库加载等,它也能支持异构平台(需要oracle gateway支持),参与复制的每个数据库可以读写,提供数据保护,但是Stream在容灾方面相对于OGG而言要弱一点,适合用于作为数据共享的应用方式,可以利用Stream复制几个从库,从库可用于查询、报表等。


二、STREAM REPLICATION实验


环境:    11.2.0.3 + OEL5.7

源端:    主机名:zlm 192.168.1.55 SID:zlm11gGLOBAL NAME:zlm11g

目标端:主机名:stream192.168.1.65 SID:strmtargetGLOBAL NAME:strmtarget

 

1.StreamsReplication准备阶段

1.1 在源端和目标端配置STREAM管理员用户

SQL> create tablespace streams_tbsdatafile '/u01/app/oracle/oradata/zlm11g/streams_tbs.dbf'size 25mreuse autoextend on maxsize unlimited;

SQL> create user strmadmin identified bystrmadmin default tablespace streams_tbsquotaunlimited on streams_tbs;

SQL> grant dba to strmadmin;

SQL> begin

  dbms_streams_auth.grant_admin_privilege(

   grantee          =>'strmadmin',   

   grant_privileges => TRUE);

end;

/


1.2 配置源端和目标端的listener.ora和tnsnames.ora(用netca自动生成)

--源端listener.ora

LISTENER =

 (DESCRIPTION_LIST =

   (DESCRIPTION =

     (ADDRESS = (PROTOCOL = TCP)(HOST = zlm)(PORT = 1521))

     (ADDRESS = (PROTOCOL = IPC)(KEY = EXTPROC1521))

    )

  )

 

ADR_BASE_LISTENER= /u01/app/oracle

 

--目标端listener.ora

LISTENER =

 (DESCRIPTION_LIST =

   (DESCRIPTION =

     (ADDRESS = (PROTOCOL = TCP)(HOST = stream)(PORT = 1521))

     (ADDRESS = (PROTOCOL = IPC)(KEY = EXTPROC1521))

    )

  )

 

ADR_BASE_LISTENER= /u01/app/oracle

 

--源端和目标端的tnsnames.ora内容一致,如下

STRMTARGET =

 (DESCRIPTION =

   (ADDRESS_LIST =

     (ADDRESS = (PROTOCOL = TCP)(HOST = stream)(PORT = 1521))

    )

   (CONNECT_DATA =

     (SERVICE_NAME = strmtarget)

    )

  )

 

ZLM11G =

 (DESCRIPTION =

   (ADDRESS_LIST =

     (ADDRESS = (PROTOCOL = TCP)(HOST = zlm)(PORT = 1521))

    )

   (CONNECT_DATA =

     (SERVICE_NAME = zlm11g)

    )

  )


1.3 配置网络连接和DatabaseLink

SQL> conn strmadmin/strmadmin@zlm11g

SQL> create database link strmtarget connect to strmadmin identified by strmadminusing 'strmtarget';

 

注意:如果db_domain值为空,并且global names设置为true的情况下,那么这里connect to关键词前面的这个“strmtarget”必须写目标端global_name的值,而using关键词后面的“strmtarget”表示的是连接目标端的SERVICE NET NAME

 

查询数据库中已有哪些DBLINK可以查询:

SQL> col owner for a15

SQL> col db_link for a15

SQL> col host for a15

SQL> select owner,db_link,host from all_db_links;


1.4 源端确认启用归档模式

SQL> conn /as sysdba

SQL> archive log list

SQL> shutdown immediate;

SQL> startup mount;

SQL> alter database archivelog;

SQL> alter database open;


1.5 设置与STREAM相关的初始化参数

SQL> alter system set global_names=true scope=both;

SQL> alter system set undo_retention=3600 scope=both;

SQL> alter system set streams_pool_size=25Mscope=spfile;


1.5.1 关于global_name参数:

To use Oracle Streams to share informationbetween databases, set this parameter to true at each database that isparticipating in your Oracle Streams environment.

官方建议设置为true,并且建立DATABASE LINK的时候名字必须为目标端数据库的GLOBALE NAME,如:create database linkstrmtarget connnect to strmadmin identified bystrmadmin using 'strmtarget';

前一个"strmtarget"为目标端数据库的globalname,后一个"strmtarget"为目标端数据库的net service name,这里创建目标端数据库时用了同一个名称,要注意,可以不同

 

    查询数据库的global name,可以执行:select * from global_name;但global_name只是一个视图,源自系统表sys.props$的global_db_name的value值,如果用alter database rename global_name to orcl;修改并无效果的话,可以尝试修改系统的sys.props$基表global_db_name属性值,语句如下:

SQL> conn /as sysdba

SQL> update sys.props$t set t.value='orcl' where t.name='global_db_name';

SQL> commit;


1.5.2 关于undo_retesion参数:

If you run one or more capture processesand you are unsure about the proper setting, then try setting this parameter toat least 3600. If you encounter "snapshottoo old" errors, then increase the setting for this parameter until theseerrors cease. Ensure that the undo tablespace has enough space to accommodate theUNDO_RETENTION setting.

如果使用stream,undo_retention至少达到3600以上,并且保证有足够的undo表空间


1.5.3 关于streams_pool_size参数:

Specifies (in bytes) the size of the OracleStreams pool. The Oracle Streams pool contains buffered queue messages. Inaddition, the Oracle Streams pool is used for internal communications duringparallel capture and apply.

    该参数默认值为0,如果MEMORY_TARGET或MEMORY_MAX_TARGET设置为非零,那么由AMM设置具体的值,该参数决定最小值;如果SGA_TARGET设置为非零,那么由ASMM设置具体的值,该参数决定最小值

 

15 MB for each capture process parallelism

250 MB or more for eachbuffered queue. The buffered queue is where the buffered messages arestored.

1 MB for each applyprocess parallelism

1 MB for each XStream outbound server

1 MB for each XStream inbound serverparallelism

For example, if parallelism is set to 3 fora capture process, then at least 45 MB is required for the capture process. Ifa database hastwo buffered queues, thenat least 20 MB is required for the buffered queues. Ifparallelism is set to 4 for an apply process, then at least 4 MB is requiredfor the apply process.

You can use the V$STREAMS_POOL_ADVICEdynamic performance view to determine an appropriate setting for thisparameter.

 

根据官方给的建议,这里给了最低的配置15M+10M=25M,不过有趣的是,当我设置为25M时,默认还是分配到了28M,相当于15+10+1+1+1=28M,不知道是否按照这样的规律。

 

NAME                                 TYPE        VALUE

----------------------------------------------- ------------------------------

streams_pool_size                    big integer 28M

 

另外,这里的“250 MBor more for each buffered queue.”我怀疑是写错了,因为根据后面的example里写的“two buffered queues, then at least 20 MB”,所以我判断,"250M"应该是"10M",如果一个buffer queue就要250M,那SGA内存就消耗太大了,不符合实际情况。需要注意的是,在生产环境中,如果该参数的值设置得太小,可能会造成进程都正常启动,但是无法同步


1.5.4 其他参数说明

以下3个参数只有在使用在downstream capture的情况下才需要配置,具体用法可以参考官方文档:

StreamsReplication Administrator's Guide——E10705-10

http://docs.oracle.com/cd/E11882_01/server.112/e10705/prep_rep.htm#i1007573

LOG_ARCHIVE_CONFIG

LOG_ARCHIVE_DEST_n

LOG_ARCHIVE_DEST_STATE_n

 

关于compatible参数,要注意的是,目标端的版本一定要大于源端的

 

另外,像很多需要在10g中配置的参数,11g中都不要求配置了,或者只用默认值就可以

alter system set aq_tm_processes=1scope=both;

alter system set job_queue_processes=10scope=both;

alter system set open_links=4scope=spfile;

alter system set statistics_level='TYPICAL'scope=both;

alter system set logmnr_max_persistent_sessions=1scope=spfile;

alter system set parallel_max_servers=20scope=both;

alter system set utl_file_dir='*'scope=spfile;

alter system set "_job_queue_interval"=1scope=spfile; --10g隐含参数,控制对job队列的检查频率,默认5


1.6 开启附加日志SUPPLEMENTALLOG

--表级添加

--无条件

ALTER TABLE hr.regions ADD SUPPLEMENTAL LOGDATA (PRIMARY KEY) COLUMNS;

ALTER TABLE hr.regions ADD SUPPLEMENTAL LOGDATA (ALL) COLUMNS;

ALTER TABLEhr.departments ADD SUPPLEMENTAL LOG GROUP log_group_dep_pk

 (department_id, manager_id) ALWAYS;

--有条件

ALTER TABLEhr.employees ADD SUPPLEMENTAL LOG DATA

 (UNIQUE, FOREIGN KEY) COLUMNS;

ALTER TABLEhr.jobs ADD SUPPLEMENTAL LOG GROUP log_group_jobs_cr

 (min_salary, max_salary);

--删除辅助日志

ALTER TABLE hr.jobs DROP SUPPLEMENTAL LOGGROUP log_group_jobs_cr;

 

--数据库级添加

ALTER DATABASEADD SUPPLEMENTAL LOG DATA

  (PRIMARY KEY, UNIQUE, FOREIGN KEY) COLUMNS;

ALTER DATABASEADD SUPPLEMENTAL LOG DATA

  (PRIMARY KEY, UNIQUE) COLUMNS;

ALTER DATABASEADD SUPPLEMENTAL LOG DATA

  (ALL) COLUMNS;

ALTER DATABASEDROP SUPPLEMENTAL LOG DATA

 (PRIMARY KEY, UNIQUE, FOREIGN KEY) COLUMNS;

 

注意:删除数据库级的SUPPLEMENTAL LOG,并不会影响原来在表级上添加的SUPPLEMENTALLOG

 

为了方便,直接在数据库级别开启辅助日志就可以了,以下是查询语句:

SQL> selectlog_mode,force_logging,supplemental_log_data_min from v$database;

 

LOG_MODE    FOR SUPPLEME

------------ --- --------

ARCHIVELOG  YES YES


2. StreamReplication参数配置

2.1 目标端创建QUEUE

SQL> conn strmadmin/strmadmin@strmtarget

SQL> begin

dbms_streams_adm.set_up_queue(

       queue_table=> 'strmtarget_queue_table',

       queue_name  => 'strmtarget_queue');

end;

/


2.2 目标端创建APPLY及APPLYRULES

SQL> begin

dbms_streams_adm.add_schema_rules(

       schema_name=> 'scott',

       streams_type=> 'apply',

       streams_name=> 'strmtarget_app',

       queue_name=> 'strmadmin.strmtarget_queue',

       include_dml=> true,

       include_ddl=> true,

       include_tagged_lcr=> false,

       source_database=> 'zlm11g',

       inclusion_rule=> true);

end;

/

 

说明:streams_type指定类型,说明是apply,queue_name是之前创建的队列名,include_tagged_lcr设置为false,主要用于在双向复制或N-WAY方式复制的环境中,不会抓取由目标端apply产生的LCR,避免形成recyclingchange,相当于在OGG中设置TRANLOGOPTIONSEXCLUDEUSER ogg。此外,假设主库已经有SCOTT的SCHEMA

 

2.3 源端创建QUEUE

SQL> conn strmadmin/strmadmin@zlm11g

SQL> begin

dbms_streams_adm.set_up_queue(

       queue_table=> 'zlm11g_queue_table',

       queue_name  => 'zlm11g_queue');

end;

/

 

说明:可以使用默认的创建队列语句,如:execute dbms_streams_adm.set_up_queue();

这样创建的队列名和队列表明默认为stream_queuestream_queue_table

创建队列语句中,queue_user可以省略,默认值为创建队列的用户,即strmadmin

 

2.4 源端创建PROPAGATION及PROPAGATIONRULES,使用SCOTT SCHEMA

SQL> begin

dbms_streams_adm.add_schema_propagation_rules(

       schema_name=> 'scott',

       streams_name=> 'zlm11g_to_strmtarget_pg',

       source_queue_name=> 'zlm11g_queue',

       destination_queue_name=> 'strmtarget_queue',

       include_dml=> true,

       include_ddl=> true,

       include_tagged_lcr=> false,

       queue_to_queue => true,

       source_database=> 'zlm11g',

       inclusion_rule=> true);

end;

/

 

说明:queue_to_queue=>true,表示该PROPAGATION进程拥有自己的job,而不会与其他的PROPAGATION进程共享,注意指定的源端和目标端队列名一定不能写错,否则会造成无法同步数据


2.5 修改PRAPAGATION计划(可选步骤)

SQL> begin

dbms_aqadm.alter_propagation_schedule(

       queue_name=> 'zlm11g_queue',

       destination=> 'strmtarget',

       latency=> 0);

end;

/

说明:该参数缺省为60秒,调整延迟为0,即立即传播


2.6 故障排错及分析*

这里执行完以后报了个错,提示:

ERROR at line 1:

ORA-24042: no propagation schedule existsfor QUEUE ZLM11G_QUEUEand DESTINATIONSTRMTARGET

ORA-06512: at"SYS.DBMS_PRVTAQIP", line 1421

ORA-06512: at "SYS.DBMS_AQADM",line 971

ORA-06512: at line 2

 

明明队列是存在的,而且目标也没有错啊,为什么还报错呢?

SQL> select owner,queue_table,name fromdba_queues where owner='STRMADMIN';

 

OWNER                          QUEUE_TABLE                    NAME

------------------------------------------------------------ ------------------------------

STRMADMIN                      ZLM11G_QUEUE_TABLE             AQ$_ZLM11G_QUEUE_TABLE_E

STRMADMIN                      ZLM11G_QUEUE_TABLE             ZLM11G_QUEUE

 

排错了半天,发现问题出在目标端数据库的global name,原来global name默认最大值为8位字符,超过8位以后的字符自动截断

SQL> conn strmadmin/strmadmin@strmtarget

SQL> col global_name for a10

SQL> select * from global_name;

 

GLOBAL_NAM

----------

STRMTARG

 

注意:这里原来是设置STRMTARGET为global name的,但是查看目标数据库才发现原来oracle自动把global name变成STRMTARG了,这样一来,之前创建的DB LINK也就等于是无效了:

SQL> col owner for a15

SQL> col db_link for a15

SQL> col host for a15

SQL> select owner,db_link,host from all_db_links;

 

OWNER           DB_LINK         HOST

--------------- ------------------------------

STRMADMIN       STRMTARGET      strmtarget  <using指定的netservice name

 

那么,此处去用错误的DBLINK寻找目标,一定是提示找不到了,解决方法:

用正确的globalname重新创建DB LINK,如果不想用这个oracle自动生成的global name,也可以去修改一下目标库的global name(必须小于8位字符),然后再创建DB LINK:

SQL> alter database rename global_name totarget;

 

Databasealtered.

 

SQL> select* from global_name;

 

GLOBAL_NAM

----------

TARGET

SQL> select value$ from sys.props$where name='GLOBAL_DB_NAME';

 

VALUE$

--------------------------------------------------------------------------------

TARGET

注意,这里改了globalname,一定也要修改源端和目标端tnsnames.ora中的service name,否则就会出现当运行lsnctl status时会发现提示:The listener supports noservices,这是因为我们经常使用的service name其实就是global name,这点千万不能搞错,而这里的数据库实例名和NETSERVICE NAME依然使用原来的STRMTARGET

SQL> select instance_name from v$instance;

 

INSTANCE_NAME

----------------

strmtarget

 

源端和目标端修改后的tnsnames.ora如下:

STRMTARGET<——NETSERVICE NAME

 (DESCRIPTION =

    (ADDRESS_LIST =

     (ADDRESS = (PROTOCOL = TCP)(HOST = stream)(PORT = 1521))

    )

   (CONNECT_DATA =

      (SERVICE_NAME =target <——GLOBALNAME

    )

  )

 

ZLM11G =

 (DESCRIPTION =

    (ADDRESS_LIST =

     (ADDRESS = (PROTOCOL = TCP)(HOST = zlm)(PORT = 1521))

    )

   (CONNECT_DATA =

     (SERVICE_NAME = zlm11g)

    )

  )

 

另外还要注意一点,如果是直接通过修改tnsnames.ora文件来修改的service_name,那么一定还要在数据库级别修改一下,否则并不是马上生效的,除非重启数据库。

SQL> show parameter service_name

 

NAME                                 TYPE        VALUE

----------------------------------------------- ------------------------------

service_names                        string      strmtarget

SQL> alter system setservice_names='target';

 

System altered.

 

SQL> showparameter service_names;

 

NAME                                 TYPE        VALUE

----------------------------------------------- ------------------------------

service_names                        string      target

 

db_name,unique_db_name,db_domain,global_name,service_name,netservice name这些name确实很容易搞不清,注意以下几点:其中global_name和net service name不属于初始化参数的值,global_names在初始化参数中的的值是true/false,和名字不是一个概念,不要混淆。service_name在初始化参数中的名称是service_names,这些细节都要注意。unique_db_name在配置DG的时候才需要用到,db_domain默认为空,如果有值,那么建立DB LINK的时候一定要注意用db_name.db_domain的形式创建

 

完成以上步骤后,删除原来错误的DB LINK,然后重建一个正确的

SQL> show user

USER is "STRMADMIN"

SQL> dropdatabase link strmtarget;

 

Database link dropped.

SQL> create database link target connect to strmadmin identified by strmadminusing 'strmtarget';

 

Database linkcreated.

 

SQL> selectowner,db_link,host from all_db_links;

 

OWNER           DB_LINK         HOST

--------------- ------------------------------

STRMADMIN       TARGET          strmtarget

 

重新修改PROPAGATION计划后,还是报了同样的错误,怎么回事呢?

继续查询,原来db_name也还是之前的那个被截短成8位字符的strmtarg

也就是说,除了global name不能超过8位字符以外,db_name也一样

其实global name=db_name.db_domain,当db_domain为空值时,他们是相等的

SQL> show parameter db_name

 

NAME                                 TYPE        VALUE

----------------------------------------------- ------------------------------

db_name                              string     strmtarg

SQL> select name from v$database;

 

NAME

---------

STRMTARG

 

难道destination是用db_name做连接,而不是global_name吗?或者是db_link?难道必须再把db_name也改掉吗?其实不用,呵呵,因为这里只需要用到db_link

SQL> show parameter name

 

NAME                                 TYPE        VALUE

----------------------------------------------- ------------------------------

db_file_name_convert                 string

db_name                              string     strmtarg

db_unique_name                       string     strmtarget

global_names                         boolean     TRUE

instance_name                       string     strmtarget

lock_name_space                      string

log_file_name_convert                string

processor_group_name                 string

service_names                       string     target

SQL> select * from global_name;

GLOBAL_NAME

--------------------------------------------------------------------------------

TARGET

 

google了一下,有人说这个“ORA-24042: no propagation schedule exists for”错误是10.2.0.3的bug,10.2.0.4之后已经解决:https://forums.oracle.com/thread/610726

但我用的11.2.0.3,显然与bug无关

 

于是又查阅了MOS上的一篇文档[ID 1059029.1],但是和CAPTURE有关的bug,但是里面提到了一个有价值的信息,就是destination这个参数和queue to queque的值是有关联的:

destination = 'dblink ' - a destination of this form is associated withqueue_to_queue = FALSE;

destination = 'schema.queue@dblink'- a destination of this form is associated withqueue_to_queue= TRUE

 

注意:queue_to_queue这个属性如果不显式指定值,默认创建PROPAGATION时是true

也就是说,指定destination的时候,值是根据queque_to_queue的值变化的

SQL> select propagation_name,source_queue_name, destination_queue_owner, destination_queue_name,destination_dblink, queue_to_queue fromdba_propagation;

 

PROPAGATION_NAME               SOURCE_QUEUE_NAME

------------------------------------------------------------

DESTINATION_QUEUE_OWNER        DESTINATION_QUEUE_NAME

------------------------------------------------------------

DESTINATION_DBLINK

--------------------------------------------------------------------------------

QUEUE

-----

ZLM11G_TO_STRMTARGET_PG        ZLM11G_QUEUE

STRMADMIN                      STRMTARGET_QUEUE

AQ$_LOCAL

TRUE

 

SQL> select schema, qname, destinationfrom dba_queue_schedules wheremessage_delivery_mode='BUFFERED';

 

SCHEMA          QNAME           DESTINATION

--------------- -------------------------------------------------------

STRMADMIN       ZLM11G_QUEUE    AQ$_LOCAL

 

SQL> select SCHEMA, QNAME, DESTINATION,SCHEDULE_DISABLED, PROCESS_NAME from DBA_QUEUE_SCHEDULES;

 

SCHEMA QNAMEDESTINATION S PROCESS

------- ---------- ------------------ ------------

AQADM MULTIPLEQAQ$_LOCAL N J000

 

关于这个AQ$_LOCAL以及其他几个属性的意思,oralce的官方解释如下:

AQ$_LOCAL inthe destination column shows that the queue to which we are propagating to isin the same database as the source queue. If thepropagation was to a remote (different) database, a database link will be intheDESTINATION column. The entry in the SCHEDULE_DISABLEDcolumn, N, means that the schedule is NOT disabled. If Y (yes) appears in thiscolumn, propagation is disabled and the schedule will not be executed. If notusing Oracle Streams, propagation should resume once you have enabled theschedule by invoking DBMS_AQADM.ENABLE_PROPAGATION_SCHEDULE (for 10.2 OracleStreams and above, the DBMS_PROPAGATION_ADM.START_PROPAGATION procedure shouldbe used). ThePROCESS_NAME is the name of the job queue process currentlyallocated to execute the schedule. This process is allocated dynamically atexecution time.If the PROCESS_NAME column is null(empty) the schedule is not currently executing. You may need to executethis statement a number of times to verify if a process is being allocated. Ifa process is at some time allocated to the schedule, it is attempting toexecute.

 

注意看第一句,AQ$_LOCAL表示传播到本地!说明之前创建PROPAGATION的语句并没有正确的配置,和是否设置queue_to_queue=true没关系,接下来删除原来的传播进程并重新创建:

SQL> exec dbms_propagation_adm.drop_propagation(propagation_name => 'zlm11g_to_strmtarget_pg' ,drop_unused_rule_sets => true);

SQL> select * from dba_propagation;

 

no rows selected

SQL> begin

dbms_streams_adm.add_schema_propagation_rules(

       schema_name=> 'scott',

       streams_name=> 'zlm11g_to_strmtarget_pg',

       source_queue_name => 'zlm11g_queue',

       destination_queue_name => 'strmtarget_queue@target',

       include_dml=> true,

       include_ddl=> true,

       inclusion_rule=> true,

       include_tagged_lcr=> false,

       queue_to_queue => true,

       source_database=> 'zlm11g');

end;

/

注意:这里必须指定DB LINK这里是target,这和我们sqlplus去连一个目标数据库@后面用的是NET SERVICE NAME是不一样的,一定要注意!

SQL> col schema for a15

SQL> col qname for a15

SQL> col destination for a40

SQL> select SCHEMA, QNAME, DESTINATION,SCHEDULE_DISABLED, PROCESS_NAME from DBA_QUEUE_SCHEDULES;

 

SCHEMA          QNAME           DESTINATION                              S PROCESS_NAME

--------------- ------------------------------------------------------- - ----------------

STRMADMIN       ZLM11G_QUEUE    "STRMADMIN"."STRMTARGET_QUEUE"@TARGET    N J000

STRMADMIN       ZLM11G_QUEUE   "STRMADMIN"."STRMTARGET_QUEUE"@TARGET    N J000

 

现在终于显示正确的DESTINATION了,和之前的创建语句相比,唯一的改动就是这句:

“destination_queue_name=> 'strmtarget_queue@target',”在目标端队列名中指定了DB LINKtarget

下面再来执行alter_propapagation_schedual的存储过程

SQL> begin

dbms_aqadm.alter_propagation_schedule(

       queue_name=> 'zlm11g_queue',

       destination=> '"STRMADMIN"."STRMTARGET_QUEUE"@TARGET',

       destination_queue => 'strmtarget_queue',--注意,由于用了queue_to_queue=ture,这句必须写

       latency=> 0);

end;

/

继续报错,换一种语法写:

SQL> begin

dbms_aqadm.alter_propagation_schedule(

       queue_name=> 'zlm11g_queue',

       destination=> 'strmtarget_queue@target',

       destination_queue => 'strmtarget_queue',

       latency=> 0);

end;

/

还是报“ORA-24042:no propagation schedule exists for QUEUE ...”的错误,崩溃了。。。

难道是11g的bug,或者11g不支持alter_propagation_schedule这个存储过程吗?

先不管了,这一步是可选步骤,只是为了让延迟=0,即捕获到的LCR一进入队列,就开始传播到指定的DESINATION,有一点可以肯定,之前做的这些工作,没有白费,由于这个非必要步骤出错,至少让我发现有2个真实的错误并纠正了:

1.超过8位的global_name自动截短至8位,造成DB LINK创建错误

2.创建PROPAGATION进程时没有指定正确的DB LINK名,导致传播到本地,即AQ$_LOCAL

先继续配置下面的步骤


2.7 源端创建CAPTURE及CAPTURERULES,使用SCOTT SCHEMA

SQL> begin

dbms_streams_adm.add_schema_rules(

       schema_name=> 'scott',

       streams_type=> 'capture',

       streams_name=> 'zlm11g_cap',

       queue_name=> 'strmadmin.zlm11g_queue',

       include_dml=> true,

       include_ddl=> true,

       include_tagged_lcr=> false,

       source_database=> 'zlm11g',

       inclusion_rule=> true);

end;

/


2.8 实例化schema

如果源端和目标端的SHCEMA用户已经同步,那么就可以跳过实例化步骤


2.8.1在目标端查询数据库现有的SCHEMA(每个username对应一个schema)

conn /as sysdba

SQL> select usernamefrom all_users;


2.8.2如果目标端没有源端的SCHEMA,创建一个空的SCHEMA并授予权限

SQL>create user scott identified bytiger;

SQL>grant dbato scott;


2.8.3exp/imp方式:

exp userid=scott/tiger@zlm11g file='/u01/scott.dmp' object_consistent=y rows=y

imp userid=system/oracle@strmtargetfile='/u01/scott.dmp' ignore=y commit=ylog='/u01/scott.log' streams_instantiation=yfromuser=scott touser=scott


2.8.4expdp/impdp方式(普通方式):

--源端和目标端创建direcotory及相应目录,并赋予读写权限

[oracle@zlm u01]$ mkdir /u01/stream_expdp

SQL> create directorystreamdp as '/u01/stream_expdp';

SQL> grant read,write on directoryexpdump to scott;

[oracle@zlm ~]$ expdp scott/tiger directory=streamdpschemas=scottparallel=2 dumpfile=scott_expdp.dmp logfile=scott_expdp.log

[oracle@zlm ~]$ scp/u01/stream_expdp/scott* sream:/u01/stream_expdp/

[oracle@zlm ~]$ impdp scott/tigerdirectory=streamdp full=y parallel=2 table_exists_action=truncatedumpfile=scott_expdp.dmp logfile=scott_expdp.log


2.8.5expdp/impdp方式(FLASHBACK_SCN方式):

conn strmadmin/strmadmin

BEGIN

DBMS_CAPTURE_ADM.PREPARE_SCHEMA_INSTANTIATION(

schema_name => 'SCOTT');

END;

/

 

SQL> showparameter  undo_retention

NAME                                 TYPE                   VALUE

 

-------------------- -------------------------------------------------

 

undo_retention                       integer                3600

 

注意:导出前一定要检查undo_retention的时间比导出时间长

 

把SCN号信息写到redo log中

SQL> exec DBMS_CAPTURE_ADM.BUILD();

SQL> select FIRST_CHANGE#,namefrom v$archived_log where dictionary_begin='YES';

 

从源库导出

expdp userid/passworddumpfile=<filename> directory=<directory_name>  flashback_scn=<first_change#>

 

注意:需要加入flashback_scn,加入scn后导出的表不会都是这个SCN号,但是都会比这个SCN号大,一般相关联的表会是同一个SCN号

 

导入到目标库

impdp userid/passworddumpfile=<filename> directory=<directory_name>


2.8.6 SCN的方式:

--获取源库互置用户的SCN

conn strmadmin/strmadmin@zlm11g

set serveroutput on

DECLARE

       iscnNUMBER; -- Variable to hold instantiation SCN value

BEGIN

       iscn := DBMS_FLASHBACK.GET_SYSTEM_CHANGE_NUMBER();

       DBMS_OUTPUT.PUT_LINE ('Instantiation SCNis: ' || iscn);

END;

/

 

--设置目标库互置用户的SCN

connect strmadmin/strmadmin@strmtarget

BEGIN

DBMS_APPLY_ADM.SET_SCHEMA_INSTANTIATION_SCN(

       source_schema_name=> 'scott',

        source_database_name => 'zlm11g',

       instantiation_scn => &iscn);

END;

/


2.9 目标端启动APPLY进程

SQL> conn strmadmin/strmadmin@strmtarget

SQL> begin

       dbms_apply_adm.start_apply(

       apply_name=> 'strmtarget_app');

end;

/

也可以写成如下形式:

SQL> begin

       dbms_apply_adm.start_apply('strmtarget_app');

end;

/

或:

SQL> exec dbms_apply_adm.start_apply('strmtarget_app');


2.9.1 如需停止APPLY进程,使用以下命令

SQL> begin

       dbms_apply_adm.stop_apply(

       apply_name=> 'strmtarget_app');

end;

/


2.10 源端启动CAPTURE进程

SQL> conn strmadmin/strmadmin@zlm11g

SQL> begin

       dbms_capture_adm.start_capture(

       capture_name=> 'zlm11g_cap');

end;

/

或:

SQL> begin

       dbms_capture_adm.start_capture('zlm11g_cap');

end;

/

或:

SQL> execdbms_capture_adm.start_capture( 'zlm11g_cap');


2.10.1 如需停止CAPTURE,使用以下命令

SQL> begin

       dbms_capture_adm.stop_capture(

       capture_name=> 'zlm11g_cap');

end;

/


2.11 启动和停止PROPAGTION(可选,默认创建完自动开启)

SQL> begin

       dbms_propagation_adm.start_propagation(

       propagation_name=> 'zlm11g_to_strmtarget_pg');

end;

/

 

SQL> begin

       dbms_propagation_adm.stop_propagation(

       propagation_name=> 'zlm11g_to_strmtarget_pg');

end;

/

 

至此,基于SCHEMA的STREAM配置完毕,如果需要查看配置中各进程的运行情况并排错,可以使用以下提供的查询语句


3. 验证各进程工作状态及排错

3.1 验证QUEUE是否成功地创建及是否运行正常

SQL> select owner,queue_table,name fromdba_queues where owner='STRMADMIN';

SQL> selectowner,queue_table,object_type from dba_queue_tables where owner='STRMADMIN';


3.2 验证APPLY进程是否被创建及是否运行正常

SQL> selectapply_name,queue_name,apply_database_link,status from dba_apply;


3.3 验证CAPTURE进程是否被创建及是否运行正常

SQL> select capture_name,queue_name,start_scn,status,capture_typefrom dba_capture;

SQL> select * from  all_capture_prepared_schemas;


3.4 验证PROPAGATION进程是否被创建及是否运行正常

SQL> selectpropagation_name,status,destination_queue_name from dba_propagation;

SQL> select * from dba_propagation;

 

ORA-25205: the QUEUE STRMADMIN.STRMTARGET_QUEUE does not exist

06-SEP-13

 

说明:出现以上情况可以重启一下PROPAGATION进程,默认创建完是自动启动的

重启PROPAGATION进程,如果无法正常地停止,可以使用FORCE=>TRUE方式

SQL> execdbms_propagation_adm.stop_propagation('zlm11g_to_strmtarget_pg',force=>true);

SQL> exec dbms_propagation_adm.start_propagation('zlm11g_to_strmtarget_pg');

SQL> select * from dba_propagation;


3.5 如果需要重新配置STREAM,可以用以下命令移除QUEUE

--源端:

begin

dbms_streams_adm.remove_queue(

queue_name              => 'zlm11g_queue',

cascade                  => true,

drop_unused_queue_table => true);

end;

/

--目标端:

begin

dbms_streams_adm.remove_queue(

queue_name              => 'strmtarget_queue',

cascade                  => true,

drop_unused_queue_table => true);

end;

/

 

说明:如果之前是使用默认方式创建队列,那么移除队列时可以直接使用以下命令:

executedbms_streams_adm.remove_queue(queue_name => ‘streams_queue’,cascade => true,drop_unused_queue_table=> true);

一旦队列被删除,之前基于队列创建的APPLY,PROPAGATION,CAPTURE进程也会一起被删除,因为这里使用了cascade=>true,drop_unused_queque_table=>true,表示删除队未使用的队列表


3.7 单独删除各进程

--删除captrue进程

SQL> exec dbms_capture_adm.drop_capture(capture_name=> 'zlm11g_cap',drop_unused_rule_sets=> true);

 

--删除propagation进程

SQL> execdbms_propagation_adm.drop_propagation(propagation_name => 'zlm11g_to_strmtarget_pg',drop_unused_rule_sets => true);

 

--删除apply进程

删除apply之前需要把所有报错信息删除

SQL> exec dbms_apply_adm.delete_all_errors;

SQL> execdbms_apply_adm.drop_apply(apply_name =>'strmtarget_app',drop_unused_rule_sets => true);


3.8 也可以使用以下命令删除STREAM全部配置

SQL> conn sys/password as sysdba

SQL> execut dbms_streams_adm.remove_streams_configuration();

 

说明:使用这个方式删除会把表的SCN号清掉,如果是用expdp/impdp方式,并用flashback_scn方式,执行该命令后,需要重新获取表的SCN并执行impdp导入。如果执行该命令报错,也可以用先删除strmadmin用户后再执行:

SQL> drop user strmadmin cascade;

SQL> executdbms_streams_adm.remove_streams_configuration();


3.9 与stream相关的几个动态性能视图:

V$STREAMS_POOL_ADVICE

V$STREAMS_CAPTURE

V$STREAMS_APPLY_COORDINATOR

V$STREAMS_APPLY_READER

V$STREAMS_APPLY_SERVER


4. 验证StreamReplication数据同步

4.1 创建测试表test

SQL> conn scott/tiger@zlm11g

SQL> create table test(id number primarykey,name varchar2(10));

 

发现源端创建的表并没有同步到备库,分别查看源端和目标端数据库的alert日志,发现主库日志正常,备库报了一个错误:

Streams APPLY STRMTARGET_APP stoppedbecause of user error 26714 due to ORA-26687. Query dba_apply_error for moredetails

Streams APPLY AP01 for STRMTARGET_APP withpid=26, OS id=7300 stopped

以stream管理员身份登录并查看dba_apply_error表:

SQL> selectAPPLY_NAME,LOCAL_TRANSACTION_ID,SOURCE_COMMIT_SCN,MESSAGE_NUMBER,ERROR_MESSAGEfrom dba_apply_error;

 

APPLY_NAME                     LOCAL_TRANSACTION_ID   SOURCE_COMMIT_SCN MESSAGE_NUMBER

------------------------------ --------------------------------------- --------------

ERROR_MESSAGE

--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

STRMTARGET_APP                 1.1.718                         1748949             1

ORA-26687: no instantiation SCN providedfor "SCOTT"."TEST" in sourcedatabase "ZLM11G"

按理说schema同步不会出现不一致,之前还多做了一步操作,原来在源端scott下有一个之前创建的test表,停止CAPTURE进程后,用stream管理员身份对其删除后,再重新启动CAPTURE,这个操作造成了instantiation SCN的不一致,解决方法如下:

--源端执行

SQL> conn strmadmin/strmadmin@zlm11g

SQL> begin

       DBMS_APPLY_ADM.set_schema_instantiation_scn(

       source_object_name  => 'scott.test',

       source_database_name=> 'zlm11g',

       instantiation_scn   => 1748949);

end;

/

--目标端执行

SQL> BEGIN

  DBMS_APPLY_ADM.EXECUTE_ERROR(

    local_transaction_id=> '1.1.718',

   execute_as_user      => FALSE,

   user_procedure       => NULL);

END;

 

或者重新实例化一下就可以了:

SQL> conn strmadmin/strmadmin@zlm11g

Connected.

SQL> setserveroutput on

SQL> DECLARE

 2  iscn NUMBER;

 3  BEGIN

 4          iscn :=DBMS_FLASHBACK.GET_SYSTEM_CHANGE_NUMBER();

 5          DBMS_OUTPUT.PUT_LINE('Instantiation SCN is: ' || iscn);

 6  END;

 7  /

Instantiation SCN is:1750929 –设置set serveroutput on才会返回到屏幕

 

PL/SQL procedure successfully completed.

SQL> connectstrmadmin/strmadmin@strmtarget

Connected.

SQL> BEGIN

  2 DBMS_APPLY_ADM.SET_SCHEMA_INSTANTIATION_SCN(

 3          source_schema_name=> 'scott',

 4          source_database_name=> 'zlm11g',

 5          instantiation_scn =>&iscn);

 6  END;

 7  /

Enter value for iscn:1750929

old  5:         instantiation_scn =>&iscn);

new  5:         instantiation_scn =>1750929);

 

PL/SQLprocedure successfully completed.

 

由于之前发生错误,目标端的APPLY进程现在的状态是ABORTED,进行实例化后需要重新启动APPLY进程,重启后继续查询目标端scott用户下的表:

SQL> conn scott/tiger

SQL> set lin 20

SQL> desc test

 Name              Null?    Type

 ----------------- -------- ------------

 ID                NOT NULL NUMBER

 NAME                       VARCHAR2(10)

 

表已经同步过来了!继续做其他同步测试


4.2 insert/update/delete测试

SQL> conn scott/tiger@zlm11g

SQL> insert into testvalues(1,'aaron8219');

 

1 row created.

 

SQL> insertinto test values(2,'zlm');

 

1 row created.

 

注意,如果是DML语句,commit之前,目标端schema是查询不到表上数据的改变的,会显示:

SQL> conn scott/tiger@strmtarget

SQL> select * from test;

 

no rows selected

 

--源端提交确认

SQL> commit;

 

Commit complete.

 

--目标端继续查询

SQL> set lin 200

SQL> select * from test;

 

        ID NAME

---------- ----------

        1 aaron8219

        2 zlm

 

--源端更新第2条记录

SQL> update test set name='aaron' whereid=2;

 

1 row updated.

 

--目标端查询

SQL> select * from test;

 

        ID NAME

---------- ----------

        1 aaron8219

        2 aaron

 

--源端删除第2条记录

SQL> delete from test where id=2;

 

1 row deleted.

 

SQL> commit;

 

Commit complete.

 

--目标端查询

SQL> select * from test;

 

        ID NAME

---------- ----------

        1 aaron8219

 

4.3 更改表结构

--源端增加一个列city

SQL> alter table test add(cityvarchar2(10));

 

Table altered.

 

--目标端查询

SQL> select * from test;

 

       ID NAME       CITY

---------- ---------- ----------

        1 aaron8219

 

测试完毕!基于schema的stream同步复制至此全部完成


5. 配置stream基于table的同步复制

先停掉之前基于scott这个schema的APPLY,CAPTRURE,PROPAGATION进程,如果不停也可以,做基于表同步的时候可以使用另一个schema下的表,但要注意重新调整streams_pool_size的值,因为之前分析过,多一个CAPTURE进程就要增加至少15M内存,多一个APPLY也要增加至少1M的空间

 

前期准备工作在配置基于schema的的同步时都已经配置好了,基于table配置基本上和基于schema的大同小异,只是用了dbms_streams_adm.add_table_rules包的存储过程,简单配置一下就可以了


5.1 源端和目标端分别创建队列

SQL> execdbms_streams_adm.set_up_queue();

 

--队列管理命令

SQL> execdbms_streams_adm.remove_queue(queue_name => 'streams_queue',cascade =>true,drop_unused_queue_table => true);

SQL> select owner,queue_table,name fromdba_queues where owner='STRMADMIN';

 

OWNER                          QUEUE_TABLE                    NAME

------------------------------------------------------------ ------------------------------

STRMADMIN                      STREAMS_QUEUE_TABLE            STREAMS_QUEUE

STRMADMIN                     STRMTARGET_QUEUE_TABLE        AQ$_STRMTARGET_QUEUE_TABLE_E

STRMADMIN                      STREAMS_QUEUE_TABLE            AQ$_STREAMS_QUEUE_TABLE_E

STRMADMIN                     STRMTARGET_QUEUE_TABLE        STRMTARGET_QUEUE

SQL> selectowner,queue_table,object_type from dba_queue_tables where owner='STRMADMIN';

 

OWNER                          QUEUE_TABLE                    OBJECT_TYPE

------------------------------------------------------------ -------------------------------

STRMADMIN                      STREAMS_QUEUE_TABLE            SYS.ANYDATA

STRMADMIN                     STRMTARGET_QUEUE_TABLE         SYS.ANYDATA

 

从以上视图可以看到,缺省不指定任何参数的话,会创建名为streams_queue的队列,streams_queue_table是对应的队列表名,对象类型是SYS.ANYDATA,加上之前的队列,现在dba_queue里管理着2条队列了


5.2 目标端配置apply

SQL> conn strmadmin/strmadmin@strmtarget

SQL> begin

dbms_streams_adm.add_table_rules(

table_name => 'scott.test_table',

streams_type =>'apply',

streams_name => 'tab_app',

queue_name => 'strmadmin.streams_queue',

include_dml => true,

include_ddl => true,

source_database => 'zlm11g',

inclusion_rule => true);

end;

/

 

--apply管理命令

SQL> select apply_name,statusfrom dba_apply;

SQL> exec dbms_apply_adm.start_apply(apply_name => 'tab_app');

SQL> exec dbms_apply_adm.stop_apply(apply_name => 'tab_app');

SQL> exec dbms_apply_adm.drop_apply(apply_name =>'tab_app',drop_unused_rule_sets => true);


5.3 源端配置传播进程

SQL> conn strmadmin/strmadmin@zlm11g

SQL> begin

dbms_streams_adm.add_table_propagation_rules(

table_name =>'scott.test_table',

streams_name => 'tab_pg',

source_queue_name =>'strmadmin.streams_queue',

destination_queue_name=> 'strmadmin.streams_queue@target',

include_dml => true,

include_ddl => true,

source_database => 'zlm11g',

inclusion_rule => true,

queue_to_queue =>true);

end;

/

 

SQL> select queue_to_queue from dba_propagation;

 

QUEUE

-----

TRUE

注意:由于配置了queue_to_queue=ture,所以这里必须新建一条队列与之前的区别开,否则会报错:

ORA-23600: cannot create PROPAGATION, ZLM11G_TO_STRMTARGET_PGalready exists

 

--propagation管理命令

SQL> select propagation_name,statusfrom dba_propagation;

SQL> exec dbms_propagation_adm.start_propagation(propagation_name => 'tab_pg');

SQL> exec dbms_propagation_adm.stop_propagation(propagation_name => 'tab_pg');

SQL> exec dbms_propagation_adm.drop_propagation(propagation_name => 'tab_pg',drop_unused_rule_sets => true);


5.4 源端配置捕获进程

SQL> conn strmadmin/strmadmin@zlm11g

SQL> begin

dbms_streams_adm.add_table_rules(

table_name =>'scott.test_table',

streams_type =>'capture',

streams_name => 'tab_cap',

queue_name => 'strmadmin.streams_queue',

include_dml => true,

include_ddl => true,

inclusion_rule => true);

end;

/

 

--capture管理命令

SQL> select capture_name,statusfrom dba_capture;

SQL> exec dbms_capture_adm.start_capture( 'tab_cap');

SQL> exec dbms_capture_adm.stop_capture( 'tab_cap');

SQL> exec dbms_capture_adm.drop_capture(capture_name =>'tab_cap',drop_unused_rule_sets => true);

 

--涉及的包及存储过程说明

DBMS_STREAMS_AUTH.GRANT_ADMIN_PRIVILEGE 授予权限

DBMS_STREAMS_ADM.SET_UP_QUEUE 创建队列

DBMS_STREAMS_ADM.ADD_TABLE_RULES 创建捕获/应用进程

DBMS_STREAMS_ADM.ADD_TABLE_PROPAGATION_RULES创建传播进程

DBMS_CAPTURE_ADM.START_CAPTURE 启动捕获进程

DBMS_APPLY_ADM.START_APPLY 启动应用进程


5.5 首先登陆scott用户创建在之前进程中需要复制的test_table表

SQL> conn scott/tiger

SQL> create table test_table(id numberprimary key,name varchar2(10));

 

Table created.

SQL> insert into test_tablevalues(1,'abc');

 

1 row created.

 

SQL> insertinto test_table values(2,'def');

 

1 row created.

 

SQL> insertinto test_table values(3,'ghi');

 

1 row created.

 

SQL> select* from test_table;

 

        ID NAME

---------- ----------

        1 abc

        2 def

        3 ghi


5.6 实例化

方法一:

SQL> conn strmadmin/strmadmin@zlm11g

SQL> DECLARE

source_scn NUMBER;

BEGIN

source_scn := DBMS_FLASHBACK.GET_SYSTEM_CHANGE_NUMBER();

DBMS_APPLY_ADM.SET_TABLE_INSTANTIATION_SCN@target(

source_object_name=> 'scott.test_table',

source_database_name=> 'zlm11g',

instantiation_scn=> source_scn);

END;

/

方法二:

conn strmadmin/strmadmin@zlm11g

set serveroutput on

DECLARE

       iscnNUMBER;

BEGIN

       iscn := DBMS_FLASHBACK.GET_SYSTEM_CHANGE_NUMBER();

       DBMS_OUTPUT.PUT_LINE ('Instantiation SCN is: ' || iscn);

END;

/

 

connect strmadmin/strmadmin@strmtarget

BEGIN

DBMS_APPLY_ADM.SET_TABLE_INSTANTIATION_SCN(

       source_object_name=> 'scott_test_table',

       source_database_name => 'zlm11g',

       instantiation_scn => &iscn);

END;

/

 

如果不进行实例初始化,会报一个ORA-26687错误:

ORA-26687: noinstantiation SCN provided for "SCOTT"."TEST_TABLE"in source database "ZLM11G"


6. 测试基于table的stream同步复制

--目标端查看表test_table

SQL> select * from test_table;

 

no rows selected

 

6.1 insert测试

--源端插入一条新数据后查询目标端

SQL> select * from test_table;

 

        ID NAME

---------- ----------

        4 jkl

 

注意:这里之所以只从第4条数据库开始同步,是因为实例化只是初始化SCN值,即源库最新的SCN值作为目标库的SCN,从这个初始点开始同步,而并不是数据的初始化,如果要初始化表的全部数据,有以下几种方法:

(1) exp/imp或expdp/impdp在源库导出表,再导入目标库

(2) rman

(3) duplication

(4) dblink复制


6.2 update测试

--源端修改新插入的记录

SQL> update test_table setid=8,name='win' where id=4;

 

1 row updated.

 

SQL> commit;

 

Commit complete.

 

--目标端查看表

SQL> select * from test_table;

 

        ID NAME

---------- ----------

        8 win


6.3 delete测试

--源端删除刚更新过的记录

SQL> delete from test_table where id=8;

 

1 row deleted.

 

SQL> commit;

 

Commit complete.

 

--目标端查看表

SQL> select * from test_table;

 

no rows selected

 

--源端查看表

SQL> select * from test_table;

 

        ID NAME

---------- ----------

        1 abc

        2 def

        3 ghi

 

注意:初始化SCN后test_table表发生的改变都可以同步到目标端,在生产环境,一定要注意先同步数据,然后再初始化SCN,这样才可以使源端和目标端表的数据完全一致

 

6.4 drop表测试

--源端删除表

SQL> drop table test_table purge;

 

Table dropped.

 

--目标端查看

SQL> select * from cat;

 

TABLE_NAME                     TABLE_TYPE

------------------------------ -----------

BONUS                          TABLE

DEPT                           TABLE

EMP                            TABLE

SALGRADE                       TABLE

TEST                           TABLE

 

DDL也顺利同步,至此,基于table的stream同步复制也全部测试完毕!

 

7. 总结

第一次接触ORACLE的STREAM,开始觉得配置似乎很麻烦,要用到很多PL/SQL的包和存储过程,对于初学的我而言确实不易,经过几天的研究,写了这篇文档,作为自己对学习STREAM一点理解的总结和经验分享,如果文中有错误之处,欢迎大家指正,谢谢!

--------------------------------------------------------------------------------------------------------

By aaron8219 Chinaunix Blog:http://blog.chinaunix.net/uid/24612962.html

原创内容,转载请注明链接,谢谢!

http://blog.csdn.net/aaron8219/article/details/11367723

你可能感兴趣的:(oracle,Stream,HA,Replication,ogg)