Schema 级的复制可以通过DBMS_STREAMS_ADM.MAINTAIN_SCHEMAS创建,经过前面表空间级的试练,接着创建schema级的复制环境还是比较简单的。

  本章示例继续沿用前章中的环境(主要是oracle环境,之前的复制环境已被清除),并设定环境如下:

  • 源数据库 sid : jssweb ,目标库 : jssstr ;
  • 复制schema:member,同步DML,DDL操作;
  • 本地捕获,双向同步(又变了哟,又改为本地捕获了);
  • DBMS_STREAMS_ADM.MAINTAIN_TTS 直接 生成 配置 ;
  • STREAMS 管理员已经创建,源和目标端通讯用的数据库链也已经创建。

  由于前面刚刚使用MAINTAIN_TTS做完表空间级的同步,因此这里准备工作可以都省掉了,如果你没有按照三思本文的介绍的顺序执行测试,务必先参考前章表空间级同步时的准备工作。

  如果是完全按照三思介绍的步骤进行的测试,千万别忘了在执行本步之前,先清除之前的复制环境,并删除目标端member下所有对象。

1、 执行创建

  除了清除之前的复制环境,删除原目标端schema中对象外,就没啥别的要做了,直接执行创建即可,创建非常简单,基本就是一个过程的事情。

  首先在源端以strmadmin登陆:

    JSSWEB> conn strmadmin/strmadmin

    Connected.

    JSSWEB> BEGIN

      2    DBMS_STREAMS_ADM.MAINTAIN_SCHEMAS(

      3      schema_names                 => ¨member¨,

      4      source_directory_object      => ¨mydt_source¨,

      5      destination_directory_object => ¨mydt_dest¨,

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

      7      destination_database         => ¨jssstr.jss.cn¨,

      8      perform_actions              => true,

      9      dump_file_name               => ¨export_member.dmp¨,

     10      log_file                     => ¨export_member_expdp.log¨,

     11      bi_directional               => true,

     12      include_ddl                  => true,

     13      instantiation                => DBMS_STREAMS_ADM.INSTANTIATION_SCHEMA);

     14  END;

     15  /

    PL/SQL procedure successfully completed.

  本过程又带来一个新的参数:instantiation ,该参数用来指定是否执行实例化,有如下几种值:

  • DBMS_STREAMS_ADM.INSTANTIATION_SCHEMA :通过expdp/impdp初始化数据,并在目标端导入数据时执行实例化,默认情况下即是该值。
  • DBMS_STREAMS_ADM.INSTANTIATION_SCHEMA_NETWORK :impdp直接通过网络传输数据而不生成dmp文件。在导入数据时执行实例化。
  • DBMS_STREAMS_ADM.INSTANTIATION_NONE :不执行实例化,该属性值仅当perform_actions参数设置为false时有效。

    注意:

    由于我们此处选择配置双向复制,因此在执行该过程时,目标端不要对member中对象做任何DML/DDL操作,以免存在数据丢失。

    MAINTAIN_SCHEMAS 过程支持同时多个schema,比如有多个schema需要复制,则在begin之前声明一个DBMS_UTILITY.UNCL_ARRAY数组变量即可,例如:

    DECLARE

      tab_schema   dbms_utility.uncl_array;

    Begin

      tab_schema(1):=¨scott¨;

      tab_schema(2):=¨member¨;

      ................

      DBMS_STREAMS_ADM.MAINTAIN_SCHEMAS(

        schema_names                 => tab_schema,

    .............

    .............

2、 测试一下

  源端执行:

    JSSWEB>  desc member.dt_tbl1;

     Name                                      Null?    Type

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

     ID                                        NOT NULL NUMBER

     NAME                                      NOT NULL VARCHAR2(30)

     VL                                                 VARCHAR2(20)

    JSSWEB>  select count(0) from member.dt_tbl1;

      COUNT(0)

    ----------

           10 2

    JSSWEB>  insert into member.dt_tbl1 values (103,¨c¨,null);

    1 row created.

    JSSWEB>  alter table member.dt_tbl1 drop column vl;

    Table altered.

    JSSWEB>  alter system switch logfile;

    System altered.

  切换到目标端查看:

    JSSSTR> select count(0) from member.dt_tbl1;

      COUNT(0)

    ----------

           103

    JSSSTR> desc member.dt_tbl1;

      名称                                      是否为空? 类型

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

     ID                                        NOT NULL NUMBER

     NAME                                      NOT NULL VARCHAR2(30)

  成功捕获、传播、并在目标端应用。

  由于我们此处配置为双向复制,双方向都是源,因此有必要在目标端也执行一些DDL,DML,看是否能够正确复制。

  这里测试在目标端创建一张表,看看是否能够传播到源端:

    JSSSTR> create table member.dt_tbl2 (id number);

    表已创建。

    JSSSTR> alter system switch logfile;

    系统已更改。

    切换到另台机器:

    JSSWEB> select table_name from dba_tables where owner=¨MEMBER¨;

    TABLE_NAME

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

    DT_TBL1

    DT_TMP

    DT_TBL2

  成功复制,双向的schema复制环境搭建成功。

3、 清除复制环境

  源和目标端分别执行DBMS_STREAMS_ADM.REMOVE。

    JSSWEB> exec dbms_streams_adm.remove_streams_configuration;  

    PL/SQL procedure successfully completed.

    JSSSTR> exec dbms_streams_adm.remove_streams_configuration;

    PL/SQL  过程已成功完成。

  然后视需要,删除相关对象/schema/tablespace即可。