Streams 特性在oracle诸多特性中属于比较灵活的一个,如果你接触oracle的时候足够久,那么一定能够理解,对于oracle而言,灵活往往也意味着复杂。这样也可以,那样也可以,究竟怎样好?一直以来,俺都认为实践更加有助于理解,为了更有有效的帮助大家的理解和学习,俺决定首先通过一个简单的示例来演示streams大致的工作方法。

一、要求

1 、 初始化参数的修改

  • global_names 必须设置为true,global_name=db_name+db_domain。
  • job_queue_processes 必须>2
  • compatible ,必须高于10.2.0,并且target中该参数值不能低于source database.
  • streams_pool_size, 指定适当的大小 ( 建议不小于200M) ,当然如果设置了sga_target,该参数也可由系统自动调节

2 、 source database 必须启用归档模式

3 、 双机互相创建database link

4 、为方便区分,我们对源和目标库的操作符做初始化

  SOURCE 端:

    SQL> conn / as sysdba

    已连接。

    SQL> set sqlprompt "JSSWEB> "

   TARGET 端:

    SQL> conn / as sysdba

    已连接。

    SQL> set sqlprompt "JSS STR > "

二、创建用户及搭建环境

这里设定我们的source数据库是jssweb,target数据库是jssstr,数据库版本10201,两机准备工作均已做好(主要指上面说的那几条)

1 、一个一个来吧,首先自然是source

-- 创建一个专用于streams的表空间,很有必要

    JSSWEB> create tablespace stream_tbs datafile ¨E:\oracle\oradata\jssweb\stream01.dbf¨ size 200m;

    表空间已创建。

    -- 创建streams管理用户,并授予dba权限

    JSSWEB> create user stradmin identified by stradmin default tablespace stream_tbs;

    用户已创建。

    -- 由于streams用户操作需要较多权限,此处仅用于演示,简便期间直接授予dba权限

    JSSWEB> grant dba to stradmin;

    授权成功。

2 、target当然也是同理,创建专用表空间及用户。

    JSSSTR> create tablespace stream_tbs datafile ¨E:\oracle\oradata\jssstr\stream01.dbf¨ size 200m;

    表空间已创建。

    JSSSTR> create user stradmin identified by stradmin default tablespace stream_tbs;

    用户已创建。

    JSSSTR> grant dba to stradmin;

    授权成功。

3 、切换回source数据库,以streams的操作用户stradmin连接

    JSSWEB> conn stradmin/stradmin

    已连接。

    创建连接到target的数据库链:

    JSSWEB> create database link jssstr connect to stradmin identified by stradmin using ¨jssstr¨;

    数据库链接已创建。

    JSSWEB> select sysdate from dual@jssstr;

    SYSDATE

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

    2008-09-01 10:18:24

    -- 创建队列

    JSSWEB> exec dbms_streams_adm.set_up_queue();

    PL/SQL  过程已成功完成。

4 、再次切换到target数据库,以streams的操作用户stradmin连接

    JSSSTR> conn stradmin/stradmin

    已连接。

    JSSSTR> create database link jssweb connect to stradmin identified by stradmin using ¨jssweb¨;

    数据库链接已创建。

    JSSSTR> select sysdate from dual@jssweb;

    SYSDATE

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

    2008-09-01 10:24:38

    -- 创建队列

    JSSSTR> exec dbms_streams_adm.set_up_queue();

    PL/SQL  过程已成功完成。

三、配置复制过程

1 、首先到source数据库

  创建捕获规则

    JSSWEB> begin

      2  dbms_streams_adm.add_table_rules(

      3  table_name => ¨scott.emp¨,

      4  streams_type => ¨capture¨,

      5  streams_name => ¨capture_stream¨,

      6  queue_name => ¨stradmin.streams_queue¨,

      7  include_dml => true,

      8  include_ddl => true,

      9  inclusion_rule => true);

     10  end;

     11  /

    PL/SQL  过程已成功完成。

  创建传播规则

    JSSWEB> begin

      2  dbms_streams_adm.add_table_propagation_rules(

      3  table_name => ¨scott.emp¨,

      4  streams_name => ¨sour_to_targ¨,

      5  source_queue_name => ¨stradmin.streams_queue¨,

      6  destination_queue_name => ¨stradmin.streams_queue@jssstr.jss.cn¨,

      7  include_dml => true,

      8  include_ddl => true,

      9  source_database => ¨jssweb.jss.cn¨,

     10  inclusion_rule => true,

     11  queue_to_queue => true);

     12  end;

     13  /

    PL/SQL  过程已成功完成。

    JSSWEB> select capture_name,status from dba_capture;

    CAPTURE_NAME                   STATUS

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

    CAPTURE_STREAM                 DISABLED

2 、切换到target数据库

  创建应用规则

    JSSSTR> begin

      2  dbms_streams_adm.add_table_rules(

      3  table_name => ¨scott.emp¨,

      4  streams_type => ¨apply¨,

      5  streams_name => ¨apply_stream¨,

      6  queue_name => ¨stradmin.streams_queue¨,

      7  include_dml => true,

      8  include_ddl => true,

      9  source_database => ¨jssweb.jss.cn¨,

     10  inclusion_rule => true);

     11  end;

     12  /

    PL/SQL  过程已成功完成。

  初始化数据,首先从源库导出,再执行导入,复制的方式很多,逻辑导入导出、rman、duplication之类的,基本上你想怎么操作都可以,这里因为只操作一个表,三思决定直接通过数据库链复制。

    JSSSTR> create table scott.EMP

      2  (

      3    EMPNO    NUMBER(4) not null primary key ,

      4    ENAME    VARCHAR2(10),

      5    JOB      VARCHAR2(9),

      6    MGR      NUMBER(4),

      7    HIREDATE DATE,

      8    COMM     NUMBER(7,2),

      9    DEPTNO   NUMBER(2)

     10  );

    表已创建。

    JSSSTR> insert into scott.emp select *from scott.emp@jssweb;

    已创建13行。

    JSSSTR> commit;

    提交完成。

  设置起始应用的scn值

    JSSSTR> DECLARE

      2  iscn  NUMBER;

      3  BEGIN

      4  iscn := DBMS_FLASHBACK.GET_SYSTEM_CHANGE_NUMBER();

      5  DBMS_APPLY_ADM.SET_TABLE_INSTANTIATION_SCN@jssstr.jss.cn(

      6  source_object_name    => ¨scott.emp¨,

      7  source_database_name  => ¨jssweb.jss.cn¨,

      8  instantiation_scn     => iscn);

      9  END;

     10  /

    PL/SQL  过程已成功完成。

  启动应用进程

    JSSSTR> exec dbms_apply_adm.start_apply(¨apply_stream¨);

    PL/SQL  过程已成功完成。

    JSSSTR> select apply_name,status from dba_apply;

    APPLY_NAME                     STATUS

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

    APPLY_STREAM                   ENABLED

3 、切换到source数据库,启动捕获进程

    JSSWEB> exec dbms_capture_adm.start_capture(¨capture_stream¨);

    PL/SQL  过程已成功完成。

    JSSWEB> select capture_name,status from dba_capture;

    CAPTURE_NAME                   STATUS

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

    CAPTURE_STREAM                 ENABLED

四、测试

如果一切顺利,我们的streams就配置好了,下面验证一下。

    JSSWEB> select *from scott.emp where empno=7499;

         EMPNO ENAME      JOB              MGR HIREDATE             COMM     DEPTNO

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

          7499 ALLEN      SALESMAN        7698 20-2 月 -81            300         30

    JSSWEB> update scott.emp set deptno=40 where empno=7499;

    已更新 1 行。

    JSSWEB> commit;

    提交完成。

    JSSSTR> select * from scott.emp where empno=7499;

         EMPNO ENAME      JOB              MGR HIREDATE             COMM     DEPTNO

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

          7499 ALLEN      SALESMAN        7698 20-2 月 -81            300         40

    JSSWEB> alter table scott.emp add tmpcol varchar2(10);

    表已更改。

    JSSSTR> desc scott.emp;

      名称            是否为空? 类型

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

     EMPNO           NOT NULL NUMBER(4)

     ENAME                    VARCHAR2(10)

     JOB                      VARCHAR2(9)

     MGR                      NUMBER(4)

     HIREDATE                 DATE

     COMM                     NUMBER(7,2)

     DEPTNO                   NUMBER(2)

     TMPCOL                   VARCHAR2(10)

  由以上测试可以看到,dml,ddl操作均可顺利传输并应用于target端,streams单表单向复制完成~~