你应该还有印象,我们在第一部分第二节的时候就已经演示了创建表级复制环境,对比全库/表空间级或schema级的复制,现在回过头来看,你可能会觉着怎么表级的复制环境这么复杂呢?其实不是这样,并非表级复制环境复杂,我们在第一部分第二章演示的正是streams实际配置时执行的过程(大部分步骤吧),如果你直接使用DBMS_STREAMS_ADM.MAINTAIN_TABLES过程创建的话,类似于schemas的复制,也就是执行一个过程的事情。

  这里一方面为了给大家演示,另外一方面也是加深大家的理解,在本部分的最后一项配置,三思决定采取生成脚本,而不直接执行配置的方式,以便大家能有机会,详细了解streams配置的实际执行步骤。

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

  • 源数据库 sid : jssweb ,目标库 : jssstr ;
  • 复制schema:member中对象,部分同步DML,部分同步DDL操作;
  • 本地捕获,单向同步;
  • DBMS_STREAMS_ADM.MAINTAIN_TABLES 生成 配置 脚本;
  • STREAMS 管理员已经创建,源和目标端通讯用的数据库链也已经创建。

1、 生成创建脚本

  由于此处也是借用前面搭建好的环境测试,因此准备工作全省下了,我们直接执行maintain_tables即可:

    JSSWEB> conn strmadmin/strmadmin

    Connected.

    JSSWEB> DECLARE

      2    tbls DBMS_UTILITY.UNCL_ARRAY;

      3  BEGIN

      4    tbls(1) := ¨member.dt_tmp¨;

      5    tbls(2) := ¨member.dt_tbl1¨;

      6    tbls(3) := ¨member.dt_tbl2¨;

      7    DBMS_STREAMS_ADM.MAINTAIN_TABLES(

      8      table_names                  => tbls,

      9      source_directory_object      => ¨mydt_source¨,

     10      destination_directory_object => ¨mydt_dest¨,

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

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

     13      perform_actions              => false,

     14      dump_file_name               => ¨export_tbls.dmp¨,

     15      log_file                     => ¨export_tbls_expdp.log¨,

     16      script_name                  => ¨configure_rep.sql¨,

     17      script_directory_object      => ¨mydt_source¨,

     18      bi_directional               => false,

     19      include_ddl                  => true,

     20      instantiation                => DBMS_STREAMS_ADM.INSTANTIATION_TABLE);

     21  END;

     22  /

    PL/SQL procedure successfully completed.

  这里有些参数你已经见过多次,有些参数,你还从未接触过:

  • Table_names :没啥好说的吧,仅提示一点,如果要复制的只有一张表的话,不需要定义DBMS_UTILITY.UNCL_ARRAY数组变量,直接调用MAINTAIN_TABLES时指定table_names等于表名即可。
  • Script_name :由于此处没有直接配置复制环境,而是生成配置脚本,该参数即是指定生成的脚本名称。
  • Script_directory_object :本参数指定生成的脚本所在目录(Oracle Directory对象,前面也提到过的)。
  • Instantiation :这个参数前面见过配置schemas复制环境里提过,不过对于表级复制,该参数值与schemas复制时的instantiation略有差异,就是将SCHEMA改为TABLE即可,各参数值代表意义与schema时相同,不再详述。

2、 查看生成脚本

  前面执行配置时将脚本生成到Directory对象mydt_source中,首先查看该目录实际指向的操作系统路径:

    JSSWEB> select * from dba_directories where directory_name=¨MYDT_SOURCE¨;

    OWNER                          DIRECTORY_NAME                 DIRECTORY_PATH

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

    SYS                            MYDT_SOURCE                    /data/oradata/jssweb/dmp

  通过上述查询确定脚本位于操作系统:/data/oradata/jssweb/dmp目录下,直接到该目录中查看生成的脚本文件,执行:

  [oracle@yans1 ~]$ more /data/oradata/jssweb/dmp/configure_rep.sql

  脚本较长,这里不全部贴出,你可以在自己的测试环境中详细浏览,如果需要修改,直接修改该脚本文件即可。

3、 执行脚本

  脚本修改完之后,源端以strmadmin登陆并执行即可,如下:

    JSSWEB> conn strmadmin/strmadmin

    Connected.

    JSSWEB> spool configure_rep.log

    JSSWEB> @/data/oradata/jssweb/dmp/configure_rep.sql

    JSSWEB> SET VERIFY OFF

    JSSWEB> WHENEVER SQLERROR EXIT SQL.SQLCODE;

    JSSWEB> 

    JSSWEB> 

    JSSWEB> 

    JSSWEB> -------------------------------------------------------------------

    JSSWEB> -- get TNSNAME and streams admin user details for both the databases

    JSSWEB> --------------------------------------------------------------------

    JSSWEB> PROMPT

  按照提示输入相关信息,总共需要6项资料,分别是源库tnsnames,streams管理员用户名和密码以及目标端的tnsnames和streams管理用户名及密码:

    JSSWEB> PROMPT ¨Enter TNS Name of site 1 as parameter 1:¨

    ¨Enter TNS Name of site 1 as parameter 1:¨

    JSSWEB> DEFINE db1                 = &1

    Enter value for 1: jssweb _172.25.13.229

    JSSWEB> PROMPT

    JSSWEB> PROMPT ¨Enter streams admin username for site 1 as parameter 2:¨

    ¨Enter streams admin username for site 1 as parameter 2:¨

    JSSWEB> DEFINE strm_adm_db1        = &2

    Enter value for 2: strmadmin

    JSSWEB> PROMPT

    JSSWEB> PROMPT ¨Enter streams admin password for site 1 as parameter 3:¨

    ¨Enter streams admin password for site 1 as parameter 3:¨

    JSSWEB> DEFINE strm_adm_pwd_db1    = &3

    Enter value for 3: strmadmin

    JSSWEB> PROMPT

    JSSWEB> PROMPT ¨Enter TNS Name of site 2 as parameter 4:¨

    ¨Enter TNS Name of site 2 as parameter 4:¨

    JSSWEB> DEFINE db2                 = &4

    Enter value for 4: jssstr _172.25.13.231

    JSSWEB> PROMPT

    JSSWEB> PROMPT ¨Enter streams admin username for site 2 as parameter 5:¨

    ¨Enter streams admin username for site 2 as parameter 5:¨

    JSSWEB> DEFINE strm_adm_db2        = &5

    Enter value for 5: strmadmin

    JSSWEB> PROMPT

    JSSWEB> PROMPT ¨Enter streams admin password for site 2 as parameter 6:¨

    ¨Enter streams admin password for site 2 as parameter 6:¨

    JSSWEB> DEFINE strm_adm_pwd_db2    = &6

    Enter value for 6: strmadmin

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

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

  执行脚本众多,某些执行结果没来的及看可能就被后续信息覆盖,没关系,在执行脚本之前我们已经将其spool到 configure_rep.log 文件中,直接查看该文件即可。

  由于脚本不会自动关闭屏蔽因此,因此最后别忘了执行spool off

    JSSWEB> spool off

4、 测试环境

  因为是单向复制,测试过程也比较简单,只需要在源端对表进行修改,然后查看目标端,看看是否被成功传播和应用即可。

    JSSWEB> insert into member.dt_tbl2 values (1);

    1 row created.

    JSSWEB> alter table member.dt_tbl2 add tname varchar2(20);

    Table altered.

    JSSWEB> alter system switch logfile;

    System altered.

  切换到目标端查看:

    JSSSTR> select * from member.dt_tbl2;

            ID TNAME

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

             1

  源端修改已经被成功同步到目标端,复制环境搭建成功。

5、 移除复制环境

  不管是哪个级别的复制环境,移除过程总是相似的,如果捕获、传播和应用进程均在运行,直接执行DBMS_STREAMS_ADM.REMOVE_STREAMS_CONFIGURATION就会报错,这里我们演示分别停止捕获传播和应用进程后,再移除整个复制环境:

  由于这里我们配置了单向复制本地传播,因此首先在源端停止捕获和传播进程:

    JSSWEB> select capture_name,status from dba_capture;

    CAPTURE_NAME                   STATUS

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

    JSSWEB$CAP                     ENABLED

    JSSWEB> exec dbms_capture_adm.stop_capture(¨JSSWEB$CAP¨);

    PL/SQL procedure successfully completed.

    JSSWEB> exec dbms_capture_adm.drop_capture(¨JSSWEB$CAP¨);

    PL/SQL procedure successfully completed.

    JSSWEB> select propagation_name,status from dba_propagation;

    PROPAGATION_NAME               STATUS

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

    PROPAGATION$_89                ENABLED

    JSSWEB> exec dbms_propagation_adm.stop_propagation(¨PROPAGATION$_89¨);

    PL/SQL procedure successfully completed.

    JSSWEB> exec dbms_propagation_adm.drop_propagation(¨PROPAGATION$_89¨);

    PL/SQL procedure successfully completed.

  移除源端整个streams配置:

    JSSWEB> exec dbms_streams_adm.remove_streams_configuration;

    PL/SQL procedure successfully completed.

  转至目标端停止应用:

    JSSSTR> select apply_name,status from dba_apply;

    APPLY_NAME                     STATUS

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

    APPLY$_JSSWEB_130              ENABLED

    JSSSTR> exec dbms_apply_adm.stop_apply(¨APPLY$_JSSWEB_130¨);

    PL/SQL  过程已成功完成。

    JSSSTR> exec dbms_apply_adm.drop_apply(¨APPLY$_JSSWEB_130¨);

    PL/SQL  过程已成功完成。

  然后接着移除streams配置即可

    JSSSTR> exec dbms_streams_adm.remove_streams_configuration;

    PL/SQL  过程已成功完成。

  然后视需要分别删除源端和目标端和streams管理帐户及相关表空间即可。