本章开始转入实践操作部分,将演示通过不同的方式创建不同的复制环境以满足不同的需求,当然,首先也还是要先从准备工作着手。

  由于Streams非常灵活(不得不再次强调),因此准备工作并不只是说要做什么,更多的描述是告诉你可以做什么,怎么做。进入10g之后streams的配置相对之前9i进行了很多改进,使得配置过程更加简化,之前需要手工执行多个过程或步骤,现在可能只需要调用一个包就可以了。不仅如此,10g之后ORACLE EM功能也相当强大,基于浏览器的可视化操作也比较易用,Streams当然也可以使用EM进行配置,不过考虑到em中操作隐含了某些操作和反馈信息,三思不准备演示通过em进行streams复制环境的搭建,感兴趣的朋友可以自行尝试(只要你明确了步骤和原理,绝对超乎你想像的简单),仍将重点放在手工使用ORACLE提供的包创建的过程上。

  在10g中,ORACLE中streams创建过程中的相关操作都打包到一个名为  DBMS_STREAMS_ADM 的包中(事实上不仅是创建,包括修改/管理等也都是使用该包),因此这里将重点描述如何使用该包创建Streams复制环境。

  DBMS_STREAMS_ADM 提供了多个过程来实现不同的复制需求:

  • MAINTAIN_GLOBAL :数据库级的流复制
  • MAINTAIN_SCHEMAS :schema级的流复制(指定的schema)
  • MAINTAIN_SIMPLE_TTS :表空间级的流复制(单个表空间)
  • MAINTAIN_TABLES :表级的流复制(指定的表)
  • MAINTAIN_TTS :表空间级的流复制(多个表空间)
  • PRE_INSTANTIATION_SETUP/POST_INSTANTIATION_SETUP :用于数据库级或表空间级的流复制,两包必须配对使用,必须手工进行实例化操作。

    提示:

    PRE_*/POST* 方式的创建两过程必须配对使用,可以实现整库或表空间级的复制,这种方式的优势是通过RMAN初始化数据,适合大数据量的复制环境搭建。MAINTAIN_*则是通过10g新提供的data pump(expdp/impdp)来初始化数据,相对来说简单、灵活一些,不仅支持整库,甚至可以精确到单个表的复制,而且也支持跨平台的操作,但是受限于expdp/impdp的效率,如果数据量大的话,创建过程可能会花费较长的时间。

一、明确需求

  在进程Streams复制环境创建之前,首先需要明确需求(这将直接影响到你的创建步骤),可从如下几个方面着手:

1、是否复制DDL操作

  上述几个过程对于DML操作默认直接复制(DML操作是指:INSERT,UPDATE,DETELE以及lob列的update操作),不过DDL语句默认是不复制的,你必须确定是否需要维护DDL操作,比如create table,alter table之类的。当然这主要还是要似你的需求而定,某些数据库是希望source和target保持一致,那么这种情况下肯定是需要同时维护dml/ddl操作的。需要希望复制DDL操作,需要在执行上述过程时显式设置include_ddl参数为true(默认情况下为false)。

    提示:MAINTAIN_SIMPLE_TTS过程没有include_ddl参数,不需要指定。另外由于apply进程并非支持所有的ddl语句,因此对于其它几个过程即使设置include_ddl参数为true,也并非所有DDL都会被应用,详细可见APPLY进程章节

2、本地捕获(Local capture)还是下游捕获(Downstream capture)

  本地捕获就是capture进程在源数据库端运行,下游捕获就是capture进程不在源数据库端运行。可以通过source_datebase参数设置本地捕获还是下游捕获。

  捕获修改的数据库被称为捕获数据库(capture database),捕获数据库即可以是源数据库,也可以是目标数据库,甚至可以是一台第三方数据库,大致如图:


  配置过程在哪台机器上执行,哪台机器就做为捕获数据库,因此如果要配置源数据库端为捕获数据库,就在源端运行配置过程,如果要配置目标端或第三方服务器为捕获数据库,就在目标端或第三方服务器上运行配置过程。

  如果源端数据库或第三方数据库做为捕获数据库,则上述过程配置一个传播进程以复制捕获到的修改到目标端数据库,如果目标端数据库做为捕获数据库的话就不需要这个过程了。

    注意:

    当bi_directional参数设置为true并且目标数据库即捕获数据库的话,capture_name和capture_queue_name两参数必须设置为null,否则过程在执行时会报错。

3、双向复制还是单向复制

  上述的包均可用来创建单向/双向的复制环境,其中的bi_directional参数用来控制复制是单向或双向:

  • 如果bi_directional 设置为false,则capture进程捕获源库发生的修改并由apply进程在目标端应用。
  • 如果bi_directional 设置为true,则数据库各自生成捕获,传输到目标端并在目标端应用。

  当复制环境为非同步,并且目标端数据库不允许修改,streams能够保持两库间共享对象的同步,不过,如果目标端发生修改,复制环境有可能失败。另外,上述过程配置的复制环境只能是简单的双向,比如a->b,或再由b->a,而不可能b->c,c->a之类复杂的循环复制。

    注意:

    如果设置bi_directional参数为true,当过程执行时,不要允许在目标端对共享对象的dml/ddl修改,当然,对于单向的复制环境就无此限制了。另外,双向复制环境还需要注意冲突解决方案的处理。

4、是否直接创建复制环境

  为什么要选择是否直接创建呢?因此上述过程即可以直接配置复制环境,也可以不执行配置,而是按照你指定的参数生成一份环境配置的脚本,一般,选择生成脚本,再通过脚本来配置可能会是下列的原因:

  • 希望在配置前全面看看执行的命令
  • 希望手工修改脚本,以进行一些自定义的配置

  是否直接配置,由包中的perform_actions参数控制,默认值为true,即直接配置复制环境。如果设置为false的话,注意同时指定script_name和script_directory_object参数,以指定脚本输出路径和名称。

5、准备如何初始化数据

  MAINTAIN_GLOBAL, MAINTAIN_SCHEMAS,  和MAINTAIN_TABLES几个过程提供了初始化数据的选项。所谓数据初始化就是指在source端准备数据,复制数据到远端,以及设置初始scn的过程。

  如果运行上述三过程来实施复制,你可以选择下列的初始化步骤:

  a>.Data Pump Export Dump File Instantiation

  首先在source端expdp导出要共享的数据库对象,然后impdp到目标端。然后执行过程时设置instantiation参数值为:

  • 运行MAINTAIN_GLOBAL过程时设置为:DBMS_STREAMS_ADM.INSTANTIATION_FULL
  • 运行MAINTAIN_SCHEMAS过程时设置为:DBMS_STREAMS_ADM.INSTANTIATION_SCHEMA 
  • 运行MAINTAIN_TABLES过程时设置为:DBMS_STREAMS_ADM.INSTANTIATION_TABLE
  b>.Data Pump Network Import Instantiation

  实际与上类似,也是借助data pump执行导出和导入,只不过导出/导入不再依赖介绍文件,而是直接通过网络传输。因此,设置instantiation参数时,参数值也有所不同:

  • 运行MAINTAIN_GLOBAL过程时设置为:DBMS_STREAMS_ADM.INSTANTIATION_FULL_NETWORK
  • 运行MAINTAIN_SCHEMAS过程时设置为:DBMS_STREAMS_ADM.INSTANTIATION_SCHEMA_NETWORK
  • 运行MAINTAIN_TABLES过程时设置为:DBMS_STREAMS_ADM.INSTANTIATION_TABLE_NETWORK
  c>.Generate a Configuration Script with No Instantiation Specified

  本操作并不执行实例化。因为执行过程时设置perform_actions参数为false,因此过程并不真正配置streams复制环境,而是生成脚本。这种情况下,配置脚本并不执行实例化并且也不会设置初始scn,你必须手动执行并确保设置适当的初始scn值。

  这种情况下,执行过程时,设置instantiation参数值为DBMS_STREAMS_ADM.INSTANTIATION_NONE。

  由于PRE_INSTANTIATION_SETUP和POST_INSTANTIATION_SETUP两过程不会执行初始化操作,因此需要你手工在执行完PRE_INSTANTIATION_SETUP后执行初始化,然后再执行POST_INSTANTIATION_SETUP过程。手工初始化数据库的方式也很多,比如通过rman duplicate,transport tablespace等等。