技术开发 频道

stream replication初步研究

   【IT168 技术文档】在9iR2中,oracle推出了一些令人兴奋的新功能,其中的logical standby database与stream replication在数据复制环境有着非常重要的意义,它们与advanced replication共同承担着企业环境中数据同步的重任。

    advanced replication分为多主复制(multimaster replication)与物化视图复制(materialized mview replication),它们都支持异构平台的数据复制;物化视图(materialized view replication)复制的核心是materialized mview(materialized mview log)的运用,依据业务可接受的数据延迟时间,对materialized mview制定相应的刷新作业;多主复制(multimaster replication)的核心是internal trigger+advanced queuing。

    dataguard分为物理备用库(physical standby database)与逻辑备用库(logical standby database),它们只支持同构平台;物理备用库承担数据安全及故障快速切换的功能;逻辑备用库承担数据安全以及较实时的报表服务等。

    stream replication是全新的信息共享机制,它通过advanced queuing、logminer 和 job scheduling等技术,构架集捕获、传播、应用为一体的企业数据共享通道,它支持异构平台以及不同的字符集之间的数据复制。

Stream体系结构

stream replication的处理过程主要分为三个方面:捕获(Capture)、传播(Propagate)与应用(Apply),其中捕获与传播进程处于stream replcation的源站点(source site),应用进程处于stream replication的目标站点(target site)。

图1 单源复制结构

        如图1所示,它是stream replication的单源复制结构,从捕获、传播、应用等演示了stream replication的“一对一”传播;如果将来业务发生变化,很容易将“一对一”传播结构扩展成“一对多”或“多对一”的传播结构;无论是“一对一”结构还是“一对多”结构,它们都是单源复制结构,单源复制结构的特点就是:一次捕获,多目标传播。


图2 多源复制结构

    图2所示,它是stream replication的多源复制结构,从捕获、传播、应用等演示了stream replication的“多对多”传播;在单源复制结构中,是不需要考虑“递归”传播,但在多源结构中,递归传播是必须禁止的,stream提供有消除递归传播的机制。

    捕获进程是后台进程,它依据源站点定义的捕获规则(rules),将符合捕获规则的事务及其它操作等(比如ddl操作),从redo logs(online redo log与archive redo log)中挖掘,并把获取的change vector包装成LCRs(logical change records)写入源站点的消息队列中,待“传播”进程传送到指定的目标队列中。

    传播进程作为job queue进行调度,它负责把源消息队列中的LCRs传播到目标消息队列中,它提供了“一对一”、“一对多”、“多对多”的传播方案,不仅可以在同构环境中传播消息,也支持在异构环境中传播消息。

    应用进程是后台进程,它负责从目标站点的消息队列中提取LCRs,并根据stream目标站点预定义的应用规则(rules),把符合应用规则的LCRs应用到目标数据库中;如果是“多源复制结构“,应用进程应用LCRs时,LGWR进程会为redo entry写入额外的标识,可以有效的避免递归传播。

    Stream功能介绍

    信息共享促使企业利用各种技术把核心数据从它们的数据库中抽取出来,许多关键的商业企业需要更成熟、统一的方案,该数据抽取方案应具有充分的灵活性以适应商业企业高速发展所带来的变化,同时最大程度地降低企业的投资。

    Stream replication通过单一的解决方案满足了大部分的数据移动、事务处理以及事件管理的需要,它为建立和运营分布式企业、数据仓库、异地容灾、异构迁移、消息队列等高可用解决方案提供了必要的能力。

    Oracle提供大量的信息共享功能模块,比如advanced queuing、advanced replication、datagaurd等,这些特性提供了具有针对性的功能,并且基于不同的底层技术,Stream replication融会了这些高可用技术的精华。

    Stream replication是开放的信息共享解决方案,它支持从Oracle到非Oracle系统的捕获和应用,事务通过透明网关被应用于非Oracle系统;stream 也允许非Oracle数据源非常简单地提交或接收变化记录,允许双向的不同类型的数据移动。

    通过stream replication,复杂的环境可受益于单一的解决方案,来简化企业的信息共享,当需求发生变化时,可以扩展stream的配置,而不必学习和集成新的产品,开发人员和管理员可以花费更少的时间,而把更多的精力用于优化解决方案上。Stream replication主要被使用于以下环境:

    数据仓库装载数据

    在瞬息万变的市场上,决策层需及时了解公司的经营状况,数据分析部门就必须提供各种各样的报表,stream replication可以满足这种较短时间延迟的数据迁移;生成和维护数据仓库很关键的工作是源源不断地从生产库抽取数据,stream replication可以捕获生产系统的变化,并将这些变化传递到数据仓库,stream replication基于logminer捕获change vector的技术消除了生产系统中不必要的中间环节。

    异构平台数据复制

    在很多异构平台数据复制中,stream replication与materialized view都可以入选。在非关键业务上,materialized view还是胜任的,在关键业务上,由于materialized view log有时太大导致materialized view难以刷新,不仅会造成数据延迟较久,甚至会对生产库造成严重影响;stream repliation通过捕获生产系统的归档日志,然后通过advanced queuing传播到目标平台的队列中,对系统的影响较小。

    异地容灾数据复制

    目前流行的异地容灾方案中,datagaurd与advanced replication都有成功的案例,也有第三方的产品(比如shareplex)。由于stream replication采用logminer+advanced queuing的技术,大大地降低了对网络带宽的需求,当然比datagaurd与advanced replication更有优势;若与shareplex对比,则略有不足,主要表现在9iR2的stream replication在生产库上对归档日志进行挖掘,对生产库还是有一些影响的;在10gR2中,oracle改善了logminer的挖掘机制,不仅可以选择在本地进行挖掘,也可以选择在远程机器进行日志挖掘。

    事件消息传播机制

    Stream replication利用advanced queuing传播事件以及消息等,开发工程师或数据库管理员可以在源库中将需要传播的消息或事件写入消息队列中,AnyData队列可以将不同类型的消息写入同一个队列中,订阅者可以直接从源队列中取出消息或事件;如果是远程应用,目标应用可以从远程消息队列中获得消息或事件。logminer写入的LCRs通常写入buffered queue,如果传播过程较慢或stream pool不足,LCRs也可能写入queue table(in DISK);用户入队的事件或消息则直接写入queue table(in Disk)。

    Stream、Dataguard、Replication对比

    dataguard在高可用及容灾方面一般是dba的首选,毕竟dataguard在这方面存在压倒性的优势,不管是物理备用库(physical standby database)还是逻辑备用库(logical standby database),它们都具有一些共同的待征。所以在选择高可用方案时需要考虑如下情况:

    配置和管理方面的成本:dataguard比stream replication简单方便

    安全与稳定方面的成本:dataguard比stream replication稳定可靠

    对于一个24x7的系统来说,这些是非常重要的,系统宕机时间的增加不仅影响着公司的形象,还会影响公司的效益;采用dataguard,数据的安全性相当有保障,物理备用库可以在最短的时间完成故障切换,逻辑备用库在保障数据安全的同时,也可以承担大量的报表等业务;由于dataguard的配置与管理比较简单,同理也降低了dba的工作强度;那什么情况下选择使用stream replication呢?

    局部复制 stream可以只复制某些表或某些模式

    异构环境 充分利用现有的设备与技术

    远程容灾 stream对网络的要求较dataguard低

    stream replication有灵活的复制策略,不仅可以配置只复制某些表,还可以配置仅复制某些表上的ddl或dml,相比dataguard必须整个数据库复制而言,可以节省相当的存储投资,毕竟对于某些海量数据而言,有许多是不必要复制的。

    如果在异构环境,即不同的操作系统,那dataguard将会束手无策,非stream replication莫属,这样可以充分利用现有的环境,配置高用可方案,在异构环境,stream replication将会是advanced replication的强劲对手。

    stream replication传播的是经过logmnr挖掘并包装的逻辑改变记录(LCRs),相比dataguard传送archived redo log、advanced replication的mview log与mview刷新的方式,stream replication对网络的需求降低了很多,在远程异地容灾的过程中,租用网络带宽是一笔较高的费用,stream replication可以适当地降低这笔费用。

    advanced replication相对于dataguard,缺点是:配置与管理较复杂、安全与稳定性不够;优点:局部复制、异构环境等。advanced replication是一种相当成熟的技术,在许多关键系统中得到成功的运用,相对于9iR2推出的stream replication而言,双方适用的环境虽然相当,比如都可以进行局部复制、异构复制、远程容灾等,advanced replication目前在稳定性与安全性方面更经得起考验。

    对比stream replication与advanced replication底层的实现技术,stream replication在实时性、稳定性、高效率、低消耗(较少的cpu/network资源)等方面更有优势,但凡一些新推出的功能,都或多或少存在一些不确定的因素。

    在10gR1中,oracle针对目前stream replication存在的弱点进行了增强,不仅提供了从advanced replication迁移到stream replication的脚本,还提供了stream replication的配置与监控工具,stream replication在配置与管理方面必将智能化、简单化,担负起与shareplex争夺企业数据复制市场的重任。

    综上所述,oracle在数据复制方面,dataguard、advanced replication、stream replication都有自己的特点及独到的地方,做为dba,用什么样的方案取决于目前的设备环境、业务需求、将来的发展趋势以及已经成熟的技术。当然,对于已经选择的数据复制方案,技术上必须有一定的把握,毕竟所有的方案都不是没有问题的,即使目前较安全、稳定、便于管理的dataguard,也会出现一些莫明其妙的事情,所以最好做到良好的监控,预防可能发生的问题,问题一旦发现,能快速地解决问题。

    Stream结构的设计与规划

    在单源复制结构中,stream结构的设计与规划,不需要考虑标识冲突,比如源库中对象的唯一索引或主键将解决此类问题;在多源复制结构中,stream结构的设计与规划,不仅要考虑数据延迟问题,还要考虑系统性能、递归传播、标识冲突等问题。

    新系统在设计时考虑将来是否有数据复制需求,如果存在数据复制需求,首先要考虑标识的冲突问题;然后要为满足性能问题提供可行性方案(比如归档切换较频繁,捕获与传播进程的工作较重),如果参与复制的产品库较多,性能问题就很关键,如果新系统上线后不久就要升级服务器的配置或更换存储设备,那对24x7的系统是很难接受的。

    某连锁超市系统每天在总部都有很多业务数据下发到连锁门店,而连锁门店系统每天也有很多销售流水要上传到总部,下发与上传数据延迟时间要求小于30分钟,对于这个案例,如何设计数据库物理结构呢?

    对于标识冲突问题,常用的有两种解决方式:一种是用全局唯一标识(GUID)做主键,一种是序列生成的流水号与门店编号组合做主键;这两种方式都很简单实用,后者在存储上占用较少的空间,也意味着更少的网络流量需求。

    对于复制性能问题,首先关注系统的物理结构设计,总部与门店表结构设计必须简洁,如果连锁门店的数目较多,对产品库服务器的压力将会很大,所以对系统中参与复制的表,要区分主次关系,将表中更新频繁的字段规划到一个表,不频繁的字段规划到一起,这样就可以减少一些不必要的流量;尽量避免系统中参与复制的表中使用lob字段,尽量减少表中的冗余字段,减少数据冗余。

    其次需要认真分析企业将来的发展形势,设计出可扩展的复制架构,在10gR1以后的版本中,stream可以配置downstream 数据库,用于处理总部系统的数据下发以及门店的上传数据,由于downstream数据库是独立主机与存储(低端),它可以利用较少的硬件投资,达到良好的复制性能。

    最后,如何最大限度减少数据传播延迟呢?在不考虑网络问题的情况下,焦点集中在产品库与downstream库之间的归档传送上,如果downstream库能很快接收来自产品库的归档,在downstream库的日志挖掘与数据下发将不是问题,如果挖掘速度不够的话,可以通过配置logmnr_max_persistent_sessions参数来增加挖掘进程的数量,这会消耗更多的内存,10gR2中downstream可以接收主库的online redo log减少数据延迟。

    如何提高产品库到downstream库的归档日志传送呢?可以采取较小的日志组,当然也可以通过配置archive_lag_target参数来限制产品库日志切换的时间,archive_lag_target参数如果设置太小,产生库的日志切换将很频繁,当然会影响生产库的性能,该参数取值在900秒左右,基本上就可以保证复制方案的要求。

    如果旧系统需要配置stream复制,不仅要考虑以上这些问题,还要考虑到目标库的数据同步问题,对于24x7的产品库来讲,如果产品库较大,那目标库数据同步的难度就较大,在10gR1中,提供了很多种目标库数据同步的方法,比如data pumb exp/imp、rman等,都可以帮我们做到目标库初始数据的同步。

    但旧系统的麻烦不止这些,如果产品库运行的是外购的软件产品,那就很难要求软件供应商根据你的需求对产品进行大的改动,只要开动脑筋,肯定可以找到解决方案的,有丰富经验的构架师与数据库管理员,是确保stream成功的前提。

    在stream复制配置过程中,产品库减少中间环节,在没有性能恶化的状态下,可以不采用downstream库来减少数据复制的延迟时间;在有性能恶化的状态下,产品库需增加中间环节,即downstream来减轻产品库的压力,结果以数据延迟时间为代价的。

    Stream在10gR1的新特征

10gR1中stream replication的新特征主要集中在五个方面:stream性能、stream配置与管理、stream replication、stream messaging以及rule interfaces等,这些功能的增强,使stream replication在企业数据复制市场有更大作为。

    在rac方面的改进

    在9i rac中,捕获(capture )进程只能从rac各节点的archived redo log中进行捕获符合rule set定义的事务及操作;在10gR1中,捕获进程可以从rac各节点的online redo log中进行捕获符合rule set定义的事务及操作,极大地降低了传播延迟;如果某实例上的捕获或应用进程宕掉,另一实例将会接管它的队列。

    downstream的应用

    在9i中,捕获进程只能在本地进行对日志进行挖掘,如果redo log文件比较大或redo log切换较频繁,日志挖掘对生产库的资源占用就较多;在10gR1中,捕获进程可以在远程数据库上进行归档日志挖掘,归档日志通过日志传送服务传送。如下图3所示:


图3 远程捕获

    Stream pool的变化

    在10gR1中,新增的stream_pool_size参数设置分配给stream的内存,它从sga中分配,建议stream pool不要小于200m;在10gR1以前的版本中,stream pool从shared_pool_size中分配,shared pool的10%分配给stream pool使用,如果shared_pool_size较小,stream的一些进程因内存不足而宕掉。如图4所示:


图4 内存结构

    支持IOT(index-organized table)及FBI(function-base index)

    在10gR1中,获捕或应用进程支持IOT及FBI,以及其它的一些数据类型(nclob、binary_float、binary_double、long、long raw)等,LCRs可以容纳这些数据类型并被传播进程传播到目标数据库。

    拷贝与移动表空间

    在10gR1中,用dbms_streams_tablespace_adm可以在两个数据库间移动或拷贝表空间,它在底层用是transportable tablespaces、data pump及dbms_file_transfer。

    清除stream replication环境

    在9iR2中,若要清除stream环境,是很较复杂的过程,很可能在数据字典中留下一些垃圾;在10gR1中,清除stream环境,调用dbms_streams_adm的remove_streams_configuration过程;清除stream环境后,想删除stream queue,可调用dbms_streams_adm的remove_queue过程,该过程有个cascade参数,当该参数为true时,将会清除所有的queue信息。

    增强的数据初始化方法

    在9iR2中,只能用exp/imp来初始化源库与目标库的数据一致;在10gR1中,可以用data pump exp/imp、rman、transportable tablespace来初始源库与目标库的数据一致。

    sysaux表空间的变化

    在10gR1中,已经将logminer默认表空间从system迁移到sysaux表空间,不需要像9iR2中调用dbms_logmnr_d的set_tablespace过程,如果执行set_tablespace将logminer默认的表空间移动到其它的表空间,将会导致一些索引失效,好在10gR1中已经可以跟踪失效的索引,并自动对系统的索引进行重建。

    在重做日志中建立数据字典

    在10gR1中,可以用dbms_capture_adm的build过程从当前的数据库中抽取数据字典到重做日志中,捕获进程可以利用redo log中的数据字典创建logminer需要的数据字典,该过程的参数fisrt_scn可以传入一个被捕获进程使用的系统改变号,捕获进程从redo log中捕获的改变将从first_scn开始,也可重置捕获进程的first_scn来清除logminer数据字典中非必须信息。

    迁移advanced replication到stream replication的脚本

    在10gR1中,stream replication的功能与稳定性都有了很大的提高,oracle为了方便用户将现有的advanced replication方案迁移到stream replication,还编写了方便用户迁移的脚本,只需要调用dbms_repcat的streams_migration过程即可。

    简化的消息管理

    在10gR1中,stream replication中提供了dbms_streams_messaging来入队列(enqueue)与出队列(dequeue)消息,过程euqueue直需把sys.anydata类型实参代入,就可以打包成LCRs入队列,在目标库中,过程dequeue则可以取出解包后的sys.anydata的值;dbms_streams_adm的过程add_message_propagation_rule可以为消息传播添加rule。

    简化的stream授权

    在10gR1中之前的版本,stream管理员需要授予很多必需的权限;但在10gR1中,则只需要授予dba权限却可满足stream的要求;另外,新的工具包dbms_streams_auth提供的过程使stream的授权更加简单。

    stream环境的时间点恢复过程(get_scn_mapping)

    在10gR1的多源复制环境中,当某个源数据库执行不完全恢复(基于时间点恢复)后,可以用dbms_streams_adm的get_scn_mapping过程,获取源数据库捕获进程的scn值,然后目标数据库应用进程对源库进行事务恢复。

    访问buffered queue信息

    在10gR1中,队列缓冲区信息可以通过新增的动态性能视图(v$buffered_subscribers、v$buffered_publishers、v$buffered_queue)来访问,分配自sga的stream pool仅存储捕获进程捕获的events,user-enquened LCR events或user-enquened non-LCR events不存入stream pool而存储在一个queue表(实际上是写入disk),捕获进程捕获的events在stream pool中超过一定的时间或者没有足够内存时,也会存入queue表(写入Disk)。

    10gR1中Stream的单源表级复制配置

Oracle stream在9iR2中被发布,在10gR1中一些新技术被揉合进去,虽然它的功能被增强了很多,但它的稳定性还有待提高;本文描述stream在9iR2中的配置步骤,同时也兼顾10gR1的新功能,很明显,10gR1中stream配置简化了很多。

    Stream的单源复制分为“一对一”与“一对多”两种,虽然可以在一个数据库模式间配置复制,但实用价值并不大,故先为大家介绍在两个数据库之间的“一对一”复制,“一对一”复制配置成功后,很容易扩展成“一对多”或多源复制。

    不管是单源复制还是多源复制,它们都有三种复制模式:

     表级复制 可以选择单独复制某些表

     模式复制 可以选择对某个模式复制

     库级复制 除sys/system模式的复制

    这三种复制模式中,步骤其实是一样的,都需要经历以下步骤,本文先以单表复制为例,给大家介绍配置方法,然后添加更多的表进行复制,介绍表级复制后,接着介绍模式复制或库级复制,这两种都比表级复制简单;从“一对一”复制扩展到“一对多”复制或多源复制,无非是重复“一对一”复制配置过程。

     配置数据库在归档模式(源库必做)

    在10gR1中,自动归档参数log_archive_start已废弃,可用archive log list在sqlplus下查看数据库是否处于归档模式;若需激活数据库的自动归档,数据库要启动到mount状态,在sqlplus下执行alter database archivelog即可,源数据库必须在归档模式。

SQL>startup mount; SQL>alter database archivelog; SQL>alter database open;

            配置初始化参数(源库、目标库必做)

    在9iR2中,需要配置以下参数让实例支持stream replication,其中job_queue_prcesses与aq_tm_processes参数可以适当地大一些,避免触发异常;若aq_tm_processes参数为0,则会导致入队的LCRs不被写入buffered queue而被直接写入queue 表(写入disk),这样从捕获到传播等环节的性能都大受影响;global_names参数必须设置为ture,compatible参数必须设置为9.2.0以上版本号,源库与目标库配置成如下所示:

SQL>alter system set compatible='9.2.0' scope=spfile; SQL>alter system set aq_tm_processes=4 scope=spfile; SQL>alter system set global_names=true scope=spfile; SQL>alter system set job_queue_processes=8 scope=spfile; SQL>alter system set log_parallelism=1 scope=spfile; SQL>alter system set logmnr_max_persistent_sessions=1 scope=spfile;

      在9iR2中,并没有为stream提供配置stream pool的参数,stream pool从shared pool中分配,约占用shared pool的10%;在10gR1及后续版本中,log_ parallelism参数已废弃,设置stream_pool_size参数为stream pool分配内存,最好大于200m,如果归档日志文件较大或日志切换较频繁,需要适量增加stream pool的内存来存储队列。

SQL>alter system set stream_pool_size=200m scope=spfile;

      参数logmnr_max_persistent_sessions控制stream源库中捕获进程的数量,每个logmnr会话产生三个相关进程:reader process、builder process、preparer process;每个logmnr会话需要10m内存,如果stream pool设置太小或没有设置,可能会触发ora-04031错误,若logmnr_max_persistent_sessions参数增加,则需要调整stream pool或shared pool。下面这段信息摘自altert_sid.log文件:

LOGMINER: Parameters summary for session# = 1 LOGMINER: Number of processes = 3, Transaction Chunk Size = 1 LOGMINER: Memory Size = 10M, Checkpoint interval = 10M LOGMINER: StopMiningThreshold = 1M LOGMINER: session# = 1, reader process P000 started with pid=16 OS id=1090 LOGMINER: session# = 1, builder process P001 started with pid=17 OS id=1092 LOGMINER: session# = 1, preparer process P002 started with pid=18 OS id=1094

      在设置参数时,open_links应该比目标站点数多,由于该参数是不允许动态修改,所以要预留的多一些;archive_lag_target参数设置时也要估计日志的切换频率以及业务最大可接受的数据延迟,设置不当将会导致日志切换频繁,造成性能问题。

      配置复制管理员并授权(源库、目标库必做)

      需要在源库与目标库上创建一个stream 复制管理员,同时也要避免使用system表空间,建议创建一个单独的表空间来容纳队列表;对于stream复制管理员,某些package需要单独授权,比如用dbms_rule_adm包来授权创建rule、rule set等权限。

create user strmadmin identified by strmadminpw default tablespace &tablespace_name quota unlimited on &tablespace; grant connect, resource, select_catalog_role to strmadmin; grant execute on dbms_aqadm to strmadmin; grant execute on dbms_capture_adm to strmadmin; grant execute on dbms_propagation_adm to strmadmin; grant execute on dbms_streams_admto strmadmin; grant execute on dbms_apply_adm to strmadmin; grant execute on dbms_flashback to strmadmin; connect / as sysdba; begin dbms_rule_adm.grant_system_privilege( privilege => dbms_rule_adm.create_rule_set_obj, grantee => 'strmadmin', grant_option => false); end; / begin dbms_rule_adm.grant_system_privilege( privilege => dbms_rule_adm.create_rule_obj, grantee => 'strmadmin', grant_option => false); end; /

      在10gR1中,stream 复制的授权方式得到了改进,dbms_streams_auth可以完成一站式的授权,避免了由授权失误而导致的复制失败,dbms_stream_adm包的grant_admin_privilege过程统一处理授权工作,revoke_admin_privilege过程统一处理收回授权工作,将dba权限授予stream管理员是必须的。

create user strmadmin identified by strmadminpw default tablespace tbs_test quota unlimited on tbs_test; grant connect, resource, dba to strmadmin; connect / as sysdba; begin dbms_streams_auth.grant_admin_privilege( grantee => 'strmadmin', grant_privileges => true); end; /

      初始化队列及队列表(源库、目标库必做)

      dbms_streams_adm的set_up_queue过程可以为stream创建复制需要的队列及队列表,它的remove_queue过程可以删除存在的队列及队列表;在用set_up_queue过程创建队列及队列表时,如果没有为队列指定名称,将会按默认的名称创建队列及队列表。

connect strmadmin/strmadminpw; exec dbms_streams_adm.set_up_queue();

      配置tns并创建db link(源库、目标库必做)

      在创建db link时,要检查open_links(>=4)与global_names(true)初始化参数的值,同时要确保配置好网络服务名,用tnsping测试后,还要在sqlplus下验证是否可以通过网络服务名进行远程登陆。

connect strmadmin/strmadminpw@&tns_name; create database link lnk_&lnk_name connect to &user_name identified by &password using ‘&service_name’;

      创建测试模式(源库可选)

      在进行stream测试时,如果源库及目标库没有现成的模式(user)用于stream复制,需要创建一个新模式及测试用的表供stream使用;在创建用于复制的表时,只在源库中创建即可,目标库可以通过exp/imp来初始化表结构及初始数据等;在10gR1及后续版本中,可以用expdp/impdp、rman等来同步目标库中的表,表创建后要授权给stream管理员。

connect / as sysdba; create user scott identified by &password default tablespace &tablesapce_name quota unlimited on &tablespace_name; grant connect,resource to scott; connect scott/&password; create table dept(id int constraint pk_dept_id primary key,name varchar2(20)); alter table dept add supplemental log group log_group_dept_pk (id) always; grant all on dept to strmadmin;

      创建复制用的表表需要注意一些细节问题:

      表必须有主键或唯一索引

      表存在组合主键或组合唯一索引时要为表添加附加日志(supplemental log)

      表的约束要指定名称(主键、唯一约束、默认值、check约束)

      主键与唯一索引保证目标库中数据应用的准确性,如果表中有组合索引,就需要为表或数据库添加附加日志,添加附加日志虽然会增加日志切换的频率,但可以避免由于更新组合主键中的某一字段而导致的更新扩大;表中的约束一定要指定名称,因为自动命名的约束在源库与目标库是不同的,当源库删除约束时,目标库中可能找不到该约束。

      配置数据库的捕获进程(源库必做)

      捕获进程依据复制源库定义的捕获规则,将符合捕获规则的事务及其它操作等(含ddl)等,从redo logs(含online redo log与archive redo log)中挖掘,并把捕获的change vector包装成LCRs(logical change records)写入源站点的消息队列中。

      规则是stream预定义的一组LCRs过滤机制,在捕获、传播、应用进程中都会用到,常用的规则有DDL rules与DML rules等,比如在配置捕获进程时,指定DML rules参数为true、DDL rules参数为false,则表示捕获进程只捕获DML(insert、update、delete、merge等)改变而不捕获DDL(alter table、truncate table等)改变。

      sub-set rules是DML rules的延伸,允许stream复制的进程对捕获、传播、应用等过程进行更精细的控制,比如可以创建只捕获、传播、应用符合某种条件的LCRs(比如delete from test where status=1)的sub-set rules。

      捕获规则分为表级捕获规则、模式级捕获规则、数据库级捕获规则等。为了简化stream的配置,dbms_streams_adm的add_table/schema/global_rules过程在配置各级捕获进程时,会根据指定的参数创建相应的捕获规则。如果想自己定义或创建各种级别的规则,可以用dbms_rule_adm的create_rule_set、create_rule、add_rule过程完成创建规则集、创建规则、并添加规则到规则集的过程。


图5 捕获进程

      在下面源库配置捕获示例中,必须注意要用stream管理员身份登陆,table_name参数输入的是schema.table_name格式,注意stream管理员必须有对schema.table_name表执行dml/ddl的权限;streams_type参数要指定是“capture”,streams_name参数可自已命名,queue_name参数是在初始化队列时dbms_streams_adm的set_up_queue过程指定的队列名,如果在初始化队列时,没有为set_up_queue过程指定队列名,那stream就用默认的队列名streams_queue,它的输入格式是strmadmin.streams_queue,include_dml与include_ddl指示dbms_rule_adm为捕获进程配置rule-sets与rules;本示例的作用是指:capture进程在挖掘日志时,需要捕获scott.dept表所发生的ddl及dml等操作。

connect strmadmin/strmadminpw@&source_tns; begin dbms_streams_adm.add_table_rules( table_name => 'scott.dept', streams_type=> 'capture', streams_name => '&capture_name', queue_name=> 'strmadmin.streams_queue', include_dml => true, include_dd=> true); end; /

      配置捕获进程有两种方式:一种是用dbms_streams_adm的add_table_rules过程,另一种是用dbms_capture_adm的create_capture过程;在用dbms_capture_adm配置捕获进程时,必须用dbms_capture_adm的prepare_table_instantiation过程来配置需要进行捕获的表,同时还必须用dbms_rule_adm来创建捕获规则及规则集,显然用dbms_capture_adm没有dbms_streams_adm方便。

      配置数据库的传播进程(源库必做)

      在stream中,events用sys.anydata类型的队列进行传播,有两种格式的events可以被传播:LCRs与User-Messages;LCRs是捕获进程在redo log中挖掘出来的dml或ddl被打包成sys.anydata格式,User-Messages是用户或应用入队的sys.anydata。


图6 传播过程

      传播进程是连接源库队列与目标库队列的桥梁,其实传播进程是一个job queue进程,所以在设置初始化参数时,要求aq_tm_processes与job_queue_processes参数大于目标站点数,避免“一对多”或“多对多”复制时产生调度拥挤。

connect strmadmin/strmadminpw@&source_tns; begin dbms_streams_adm.add_table_propagation_rules( table_name => 'scott.dept', streams_name => '&propagatin_name', source_queue_name => 'strmadmin.streams_queue', destination_queue_name=> 'strmadmin.streams_queue@&target_lnk', include_dml => true, include_ddl => true, source_database => '&source_lnk'); end; /

      在上例的add_table_propagation_rules过程中,table_name参数是需要传播到目标库的表,格式是schema.table_name,streams_name参数可随意,即传播名称,source_queue_name参数是源队列名,默认是stremadmin.streams_queue,destination_queue_name参数中的@target_db_lnk是数据库链接,即指向目标库的strmadmin.streams_queue,include_dml与include_ddl参数表示可以传播scott.dept表的dml/ddl操作到目标库,source_datbase参数表示指向源库的数据库链接。

      传播进程的传播类型有三种:表级、模式、全库。分别由dbms_streams_adm package的add_table/schema/global_propagation_rules过程来完成,传播规则可以与捕获规则不同;传播进程也可用dbms_propagation_adm的create_propagation过程创建,则传播规则需手工配置,而它的job queue进程必须用dbms_aqadm 进行配置。


图 7传播进程

      如图7所示,传播进程由job queue进程来代理,但它与job进程有一些细微的区别,比如传播进程的interval属性为null时,表示传播进程在当前的任务完成后(默认单次任务时间是4分10秒),潜伏3秒,再进入下次任务处理中,如果当前队列为空,则一直处于潜伏状态,直到被捕获进程唤醒,如果想改变传播进程的调度信息,可以使用dbms_aqadm package的alter_propagation_schedule过程。

      当启动配置有stream的数据库时,需要先启动目标库,然后再启动源库,否则在源库启动时,在alert_sid.log中报ora-2068/1033号错误,有可能导致stream的捕获进程的状态置为"paused for flow control",但不需要太担心,重启源库捕获进程就正常啦,在动态性能视图v$streams_capture的state记录了捕获进程的状态,也可查dba_capture字典表。

      目标库初始数据同步(目标库必做)

      当源库配置捕获、传播进程后,需要将源库待复制的表与目标库进行同步,在9iR2中只能使用exp/imp来同步初始数据,在10gR1及后续版本中,还可以用expdp/impdp、rman等进行源库与目标库的初始数据同步(设置目标库中对象的scn与源库相同)。

      exp/imp、expdp/impdp适用于表级、模式级、库级初始数据同步,rman适用于数据库规模较大的初始数据同步;expdb/impdp与exp/imp相比,同步初始数据的速度更快,rman在全库复制方面大大降低初始数据同步的时间。

      在用exp/imp时,源库导出表、模式或库,在目标库导入表、模式或库。如果源库中的表创建了附加日志(supplemental log),在目标库需要手工删除导入的附加日志,通过数据字典视图user_log_groups可知那些表存在附加日志。用exp/imp表级(模式/库级)导出(9iR2/10gR1通用)示例:

exp scott/tiger@&source_tns FILE=exp.dmp TABLES=dept OBJECT_CONSISTENT=y imp scott/tiger@&target_tns FILE=exp.dmp FULL=y STREAMS_INSTANTIATION=y connect scott/tiger@&target_tns; alter table scott.dept drop supplemental log group log_group_dept_pk;

      设置初始scn(目标库必做)

      用exp/imp、expdm/impdp、rman进行数据同步,同时也可以对初始scn进行设置,比如exp时OBJECT_CONSISTENT=y参数与imp时STREAMS_INSTANTIATION=y参数,它们就已经完成了初始scn的设置。

      在不需要初始数据同步的情况下,可以跳过用exp/imp初始表结构与数据,可以直接在源库与目标库创建表,用dbms_apply_adm的set_table/schema/global_instantiation_scn过程直接设置目标库中表的初始scn。如下例所示,用stream管理员连接到源库,用dbms_flashback的get_system_change_number过程求得源库的scn,然后调用set_table_instantiation_scn过程调置目标库的表的初始scn。

connect strmadmin/strmadminpw@&source_tns; declare v_scn number; begin v_scn := dbms_flashback.get_system_change_number(); dbms_apply_adm.set_table_instantiation_scn@&target_lnk( source_object_name => 'scott.dept', source_database_name => '&source_lnk', instantiation_scn => v_scn); end; /

      过程set_table_instantiation_scn的参数source_database_name代表链接到源库的数据库链接,@target_lnk代表链接到目标库的数据库链接,它调用的是目标库上dbms_apply_adm的set_table_instantiation_scn过程;参数source_object_name指需要从源库取得该对象的scn,并将获得的scn同步到目标库中的对象;参数instantiation_scn是从源库求得的scn值;设置了表、模式、库的初始scn后,可以从dba_apply_instantiated_objects字典表中确认;感觉这个过程的实现比较别扭…理解起来比较难。

      配置并启动目标库的应用进程(目标库必做)

      当源库的捕获、传播进程配置完毕,目标库的初始数据同步及初始scn设置后,就可以配置并启动目标库的应用进程;可以用dbms_streams_adm的add_table/schema/global_rules过程来配置应用进程,也可以有dbms_apply_adm的create_apply及alter_apply等过程来创建并配置应用进程,以下是用dbms_streams_adm配置应用进程的示例:

connect strmadmin/strmadminpw@&target_tns; begin dbms_streams_adm.add_table_rules( table_name => 'scott.dept', streams_type => 'apply', streams_name => '&apply_name', queue_name=> 'strmadmin.streams_queue', include_dml=> true, include_ddl => true, source_database => '&source_lnk'); dbms_apply_adm.start_apply(apply_name => '&apply_name'); end; /

      在用dbms_streams_adm的add_table_rules过程配置应用进程时,它的参数streams_type必须是apply,参数streams_name可随意,参数source_database代表链接到源库的数据库链接,include_dml/ddl指示应用进程可以应用捕获到的dml及ddl操作。

      配置完应用进程后,需要用dbms_apply_adm的start_apply过程来启动应用进程,如果想修改应用进程的参数,需要先停下应用进程,然后修改后再启动应用进程,如果不停下应用进程修改应用参数将会报错,修改应用参数示例:

connect strmadmin/strmadminpw@&target_tns; begin dbms_apply_adm.stop_apply( apply_name => '&apply_name'); dbms_apply_adm.set_parameter( apply_name => '&apply_name', parameter => 'disable_on_error', value => 'n'); dbms_apply_adm.start_apply( apply_name => '&apply_name'); end; /

      如示例所示,用dbms_apply_adm的stop_apply过程停下应用进程,用set_parameter过程修改应用进程的参数,用start_apply过程来启动应用进程,可以通过all_apply_parameters字典表查看应用进程的当前的参数设置。

      启动源库的捕获进程(源库必做)

    其实把启动源库的捕获进程安排到最后不是必须的,但这样做的好处是避免源库的队列因没有传播而过度臌胀,启动源库的捕获进程用dbms_capture_adm的start_capture过程,停止源库的捕获进程用stop_capture过程。

connect strmadmin/strmadminpw@&source_tns; begin dbms_capture_adm.start_capture( capture_name => '&capture_name'); end; /

    stream复制环境的监控(源库与目标库必做)

    如果运气好的话,单源复制已经成功运作啦,实际上在手工配置过程中,稍微的一些失误都可能导致复制的失败,主要是stream在配置过程中,有些过程对输入的实参没有验证有效性,比如add_table_rules过程的source_database_name参数随便输入都不会报错,实际上该实参所代表的database link如果不存在,复制将不会成功。

    当我们配置stream成功后,还要面对相当多的未知错误,如何监控stream环境?确保能及时发现并解决复制故障;主要从捕获、传播、应用三个方面进行监控:捕获与传播进程集中在源库,应用进程在目标库,所以对它们的监控脚本一般会分成源库与目标库两部分,然后通过linux下的cron守护进程进行调度。

    源库需要监控那些资源?

    ?  初始化参数     某些初始化参数修改会导致复制环境失败

    ?  数据库链接    确保数据库链接可以正常工作

    ?  捕获进程状态  确保复制期间捕获进程的状态一直是enabled

    ?  传播进程状态  确保传播job存在及它的broken状态是N

    ?  后台警告日志  收集警告日志并识别它是否是stream引起的

    ?  队列是否溢出  队列溢出将严重影响复制的性能

    目标库需要监控那些资源?

    ?  初始化参数     某些初始化参数修改会导致复制环境失败

    ?  数据库链接    确保数据库链接可以正常工作

    ?  应用进程状态  确保复制期间应用进程的状态一直是enabled

    ?  后台警告日志  收集警告日志并识别它是否是stream引起的

    ?  应用错误字典  查询dba_apply_error字典确定应用进程是否遇到麻烦

    ?  数据延迟时间  确保数据延迟时间在业务系统接受的范围内

     

    捕获进程与应用进程在实例启动时将恢复到实例关闭前的状态,如果实例关闭前它们的状态是enabled,实例启动后它们的状态依旧会是enabled状态;传播进程是job进程,如果job进程试探16次失败后,传播job将会被自己删除,所以传播进程不仅要监控它的broken状态是否是N,还要监控它们是否存在,如果传播job不存在,需要用dbms_aqadm的schedule_propagation过程重新配置传播job。

    在9iR2及10gR1版本,oracle在metalink分别为它们提供了监控stream的脚本,该脚本涵盖了stream复制的各个方面,比我上面所示的更为详细,如果有metalink帐号的话,你可以通过查看Note:273674.1,查看9i及10g的stream监控脚本。

    在10gR1中,metalink也为stream复制提供了基于命令行的监控工具,它支持9iR2及10gR1,可以通过Note:290605.1找到strmmon工具,按照该页面的描述,下载、编译并运行strmmon工具,strmmon可以监控stream复制中源库与目标库中的LOG、CPxx、MEM%、Qx、PRxx、APxx等方面,可按如下方法编绎:

    tar -xf strmmon.tar

    make -f strmmon.mk strmmon

 

    Stream在10gR2的新特征

    在新推出的10gR2中,stream的增强与10gR1很相似,也集中在以下几个方面:stream性能增强、stream配置与管理增强、stream复制增强、stream监控增强、stream规则接口增强、stream信息提供增强等。

    实时远程捕获(Real-Time DownStream Capture)

    在9iR2中,stream不支持downstream capture,stream的捕获进程只能在本地处理归档;在10gR1中,stream支持Archvied Log-DownStream Capture,在远程数据库挖掘从源库传送过来的归档日志;在10gR2中,stream支持Real-Time DownStream Capture,可以在远程数据库的standby redo log中挖掘从源库传来的事务,即减轻了源库的压力,又降低了源库到目标库间数据同步的延迟。Real-Time DownStream Capture如下图所示:


图8实时远程捕获过程

    Stream Pool的变化

    较10gR1而言,stream pool主要有2个方面的改进。一是stream pool的自动共享内存管理,如果sga_target参数大于零,则stream pool从sga_target中动态分配,可避免因stream pool评估不足带来的问题;二是在oem中提供了配置与管理stream pool的GUI接口,可以在web browse中控制stream pool的大小。

    传播进程的变化

    在10gR1中,传播进程是由dbms_aqadm来调度的,实际没有启动及停止传播进程的接口;在10gR2中,由dbms_propagation_adm包提供了start_propagation与stop_propagation过程来启动与停止传播进程。

    stream复制配置的简化

    在10gR2中,stream的配置已经做了很大的简化,以前需要执行多个过程才可以搞定的事情,现在只需要执行很少的核心过程就可以搭建起复制环境,了解并研究这些过程的功能,可以使我们在实际项目选择合适的过程。

    包dbms_streams_adm新提供的用于简化复制环境配置的过程,其中maintain_*类过程主要利于10g中的expdp与impdp来同步初始数据,而*_instantiation_setup过程主要利用rman来同步初始数据。

    pre/post_instantiation_setup过程需配对使用,它们可以完成global(全库)与transportable tablespace(表空间)两种级别的复制配置;maintain_global、maintain_schemas、maintain_simple_tts、maintain_tables、maintain_tts等过程可以完成从库级、模式级、表空间级、表级等各种各样的复制配置。

    由于pre/post_instantiation_setup过程用rman进行同步初始数据,它们对于数据库的大小没有什么限制,通常数据库比较大,用pre/post_instantiation_setup过程就比较有优越性,因为rman可以减少数据同步时间,但pre/post_instantiation_setup过程在配置全库复制或表空间级复制时,不能初始化目标库的scn。

    由于maintain_global/schemas/tables/tts/simple_tts过程用expdp与impdp进行同步初始数据,一般来讲,如果数据库较小,那用maintain_global/schemas/tables/tts/simple_tts过程会比较简单一些,几乎只执行maintain_global/schemas/tables/tts/simple_tts中的一个过程就可以搞定全库、表空间、模式、表级复制中的某种类型的复制配置,而且这些过程在同步数据时,还可以完成初始化目标数据库的scn;如果你不是很熟悉rman,那maintain_*过程也可以帮我们完成想要的复制配置;如果仅仅从功能上讲,maintain_*过程更灵活一些,由于pre/post_instantiation_setup过程只可以完成全库与表空间级的复制,那表级、模式级复制就非maintain_*过程莫属。

    rman在stream中的应用

    在10gR2中,rman新的transport tablespace命令,源库的表空间在online的状态,可以设置表空间的instantiation,目标库可以用dbms_streams_tablespace_adm的attach_tablespaces过程添加该表空间,也可以impdp来添加该表空间;当复制环境中源库与目标库的处于不同的平台,但有相同的endian format时,rman的convert database命令可以为目标库设置instantiation状态。

    应用进程允许应用重复行

    在10gR2以前的版本,如果应用进程在应用LCRs时遇到表中有重复记录时,将会在dba_apply_error中记录一个异常;在10gR2中,应用进程的allow_duplicate_rows参数可以控制应用进程允许应用进程应用重复的LCRs,应用进程的参数查dba_apply_parameters字典表,修改该参数需用dbms_apply_adm的set_parameter过程;该参数默认是不允许应用进程应用重复的LCRs。

select apply_name,parameter,value from dba_apply_parameters APPLY_NAMEPARAMETER VALUE ------------------------------ ------------------------------------- ------------ APPLY$_TEST96_22 ALLOW_DUPLICATE_ROWS N

    监控长时间运行的事务

    在10gR2中,为了监控长时间运行的事务,stream提供了V$STREAMS_TRANSACTION字典表,不仅可以查看捕获进程或应用进程已经处理过的长时间运行的事务,而且可以查到该长事务处理了多少LCRS、开始时间与结束时间等。

select streams_name,streams_type,total_message_count from v$streams_transaction;

    应用进程的LCRs应用增强

    在10gR1及以前的版本中,应用进程只能应用row LCRs,而不能应用user-constructed LCRs;在10gR2中,应用进程可以应用队列中的row LCRs与user-constructed LCRs,极大地增强了应用进程的功能。

    10gR2中Stream的多源全库复制配置

在10gR2中,oracle简化了stream复制配置的过程,以前需要为stream的捕获、传播、应用进程配置的步骤已经被dbms_streams_adm新提供的过程替代,只需要一两个过程就可以完成stream复制配置啦,下文将以stream的多源全库复制配置为例,介绍dbms_streams_adm新提供的pre_instantiation_setup/post_instantiation_setup过程。

    源库与目标库初始化参数设置

alter system set aq_tm_processes=4 scope=spfile; alter system set job_queue_processes=5 scope=spfile; alter system set global_names=true scope=spfile; alter system set streams_pool_size=51m scope=spfile;

    说明:在生产库上,streams_pool_size参数最好大于200m,如果不设置streams_pool_size参数,streams_pool_size池将用shared_pool_size池十分之一的内存;在10gR2中,AWR可以监控streams_pool_size池的使用情况,也可从v$sgastat中查看streams_pool_size池的使用,根据监控的结果,为streams_pool_size设置合适的值。

    源库与目标库网络服务名设置

    确保源库与目标库的网络服务名配置正确,可以用tnsping测试通过。

TEST96 = (DESCRIPTION = (ADDRESS_LIST = (ADDRESS = (PROTOCOL = TCP)(HOST = 10.0.108.95)(PORT = 1521))) (CONNECT_DATA = (SERVICE_NAME = test))) TEST99 = (DESCRIPTION = (ADDRESS_LIST = (ADDRESS = (PROTOCOL = TCP)(HOST = 10.0.108.99)(PORT = 1521))) (CONNECT_DATA = (SERVICE_NAME = test)))

    源库与目标库复制管理员创建

create user strmadmin identified by &passwd default tablespace &tbs_name quota unlimited on &tbs_name; grant dba to strmadmin;

    说明:在9iR2,如果复制管理员不授予dba角色,所有的ddl操作因权限不足被忽略;在10gR2中,复制管理员的授权已经做了简化,不必象9iR2一样授予复制管理员一堆权限,只授予dba权限就够啦。

    源库与目标库数据库链的创建

connect strmadmin/strmadminpw@test96; create database link t99.net connect to strmadmin identified by &passwd using 'test99'; connect strmadmin/strmadminpw@test99; create database link t96.net connect to strmadmin identified by &passwd using 'test96';

    说明:必须确保源库与目标库的数据库链是连通的,否则在使用dbms_streams_adm的pre_instantiation_setup/post_instantiation_setup过程配置复制时会失败;database link的命名必须使用db_name.domain的格式,否则pre_instantiation_setup/post_instantiation_setup过程配置复制时会报错。

    源库与目标库数据库必须归档

shutdown immediate; startup mount; alter database archivelog; alter database open;

    执行pre_instantiation_setup过程

    首先介绍一下pre_instantiation_setup过程的参数:

    maintain_mode参数可取global与 transportable tablespaces,如果该参数取global时,表示stream进行全库复制,否则表示stream进行表空间复制,需要在tablespace_names参数中指定待复制的一个或多个表空间。

    perform_actions参数为true,stream配置脚本执行过程将记录在dba_recoverable_script字典表,如果pre_instantiation_setup执行时遇到错误,可以通过执行dbms_steams_adm的recover_operation过程在更正错误后继续执行stream复制配置。

    source_database/destination_database参数是指向源库与目标库的database link,该必须确保正确啊,否则pre_instantiation_setup过程将会失败,报ora-23621错误,解决办法就是清空dba_recoverable_*字典表,更正错误后再执行pre_instantiation_setup过程。

    bi_directional参数设置为true时,表示是stream是多源复制,即目标与源库双向复制对象与数据,否则只从源库向目标库复制对象与数据;exclude_schemas参数指出全库复制时不参与复制表空间,如果有多个表空间不参与复制的话,可以用逗号分开;start_processes参数指stream配置完成后启动捕获、传播及应用进程。

SQL>connect strmadmin/strmadminpw@test96; declare v_tts dbms_streams_tablespace_adm.tablespace_set; begin dbms_streams_adm.pre_instantiation_setup( maintain_mode => 'global', tablespace_names => v_tts, source_database => 't96.net', destination_database => 't99.net', perform_actions => true, bi_directional => true, include_ddl => true, start_processes => true, exclude_schemas => 'wmsys,strmadmin,dbsnmp,tsmsys,outln', exclude_flags => dbms_streams_adm.exclude_flags_unsupported + dbms_streams_adm.exclude_flags_dml + dbms_streams_adm.exclude_flags_ddl); end; /

    执行pre_instantiation_setup过程出错处理

    在执行pre_instantiation_setup过程时可能会出错,比如报错ora-23621: Operation corresponding to script FC582A17725C1841E030007F01000822 is in progress等错误,更正引起pre_instantiation_setup过程出错的原因,然后调用dbms_streams_adm的recover_operation过程继续进行stream复制配置,也可用recover_operation过程清空dba_recoverable_*字典表,重新执行pre_instantiation_setup过程。

begin dbms_streams_adm.recover_operation( script_id => 'FC582A17725C1841E030007F01000822', operation_mode => 'FORWARD'); end; /

    说明:recover_operation过程是10gR2新增的功能,它不仅可用于pre_instantiation_setup过程中,还可以用于maintain_global/scheams/tables/tts/simple_tts等过程;recover_operation过程的operation_mode参数有三个取值:forward、rollback、purge,forward表示继续进行,rollback表示回滚操作,purge表示清除dba_recoverable_script字典表。

    用rman复制源库到目标库

    对源库用rman进行备份,并拷贝源库的备份集到目标库,同时将目标库down下来,启动nomount状态,用于目标库的恢复操作;备份完毕后,需求得源库当前的scn,用于目标库恢复到源库当前的scn;目标库恢复后需要重新创建database link,必须确保源库与目标库的database link可以连接,否则post_instantiation_setup过程将会失败。

$rman nocatalog target / $rman>backup database plus archivelog delete input; SQL>connect strmadmin/strmadminpw@test96; SQL>set serveroutput on size 1000 SQL>declare until_scn number; begin until_scn:= dbms_flashback.get_system_change_number; dbms_output.put_line('until scn: '||until_scn); end; / until scn: 429596 $rman nocatalog target / $rman> connect auxiliary sys/sys@test99; $rman> run { set until scn 429596; duplicate target database to 'TEST' nofilenamecheck open restricted; } SQL>alter database rename global_name to test99.net; SQL>connect strmadmin/strmadminpw@test99; SQL>drop database link t96.net; SQL>create database link t96.net connect to strmadmin identified by &passwd using 'test96';

    执行post_instantiation_setup过程

    用post_instantiation_setup过程与pre_instantiation_setup过程配置stream复制时,它们必须成对使用,而且只需要在源库执行即可,当post_instantiation_setup过程执行成功后,stream复制基本上已经成功,当执行post_instantiation_setup过程时,需要注意的参数是instantiation_scn,它的取值是我们从源库上获的scn的值减1(429595)。

SQL>connect strmadmin/strmadminpw@test96; SQL>declare v_tts dbms_streams_tablespace_adm.tablespace_set; begin dbms_streams_adm.post_instantiation_setup( maintain_mode => 'global', tablespace_names => v_tts, source_database => 't96.net', destination_database => 't99.net', perform_actions => true, bi_directional => true, include_ddl => true, start_processes => true, instantiation_scn => 429595, exclude_schemas => ' wmsys,strmadmin,dbsnmp,tsmsys,outln', exclude_flags => dbms_streams_adm.exclude_flags_unsupported + dbms_streams_adm.exclude_flags_dml + dbms_streams_adm.exclude_flags_ddl); end; / SQL>connect sys/sys@test99 as sysdba; SQL>alter system disable restricted session;

    说明:当post_instantiation_setup过程执行成功后,注意取消会话限制,然后要测试stream的双向复制配置是否成功,测试方法比较简单,在源库与目标库下各创建一个schema,并创建一表些并添加测试数据:

    ?  在test96上创建schema并在该schema下创建一些对象,可以在test99上看到

    ?  在test99上创建schema并在该schema下创建一些对象,可以在test96上看到

    stream双向复制中avoid change cycling

    关于多源复制中redo entry的递归应用问题,stream中有很好的消除机制,源库与目标库正常事务写入的redo entry的tag是00,而源库与目标库的apply进程应用LCRs产生的redo entry的tag标志是非00值,这样源库与目标库的捕获进程在捕获的redo entry中,过虑掉tag值非00的redo entry项,就可以消除多源复制的change cycling。

    查看源库与目标库应用进程的tag:

SQL>column apply_name heading 'apply process name' format a30 SQL>column apply_tag heading 'tag value' format a30 SQL>connect sys/sys@test96 as sysdba; SQL>select apply_name, apply_tag from dba_apply; Apply Process Name Tag Value APPLY$_TEST96_42 010781 SQL>column apply_name heading 'apply process name' format a30 SQL>column apply_tag heading 'tag value' format a30 SQL>connect sys/sys@test99 as sysdba; SQL>select apply_name, apply_tag from dba_apply; Apply Process Name Tag Value APPLY$_TEST99_15 010498

    10gR2中Stream的单源模式复制配置

上一节介绍了per/post_instantiation_setup过程进行多源全库复制(rman同步数据)的配置步骤;本节介绍maintain_global/schemas/tables等过程配置复制(expdp/impdp同步数据)的步骤,这些过程配置复制步骤是相似的,现以模式级复制为例,介绍maintain_schemas过程的配置复制的方法。

    关于maintain_global过程的测试案例,见http://blog.itpub.net/post/96/36365

    关于maintain_tables过程的测试案例,见http://blog.itpub.net/post/96/37044

    无论是用per/post_instantiation_setup过程还是maintain_schemas过程进行复制配置,它们前期的准备工作都是相似的,现写出maintain_schemas过程前期准备的步骤,可以将上一节中介绍的per/post_instantiation_setup过程的配置步骤拷贝过来用的:

    源库与目标库初始化参数设置

    源库与目标库网络服务名设置

    源库与目标库复制管理员创建

    源库与目标库数据库链的创建

    源库与目标库数据库必须归档

    源库与目标库数据库创建目录

    复制前期的准备工作就绪后,需要确定maintain_schemas过程参数的实参,特别要注意schema_names参数,它有两种格式:一种是dbms_utility.uncl_array类型的变量,一种是以逗号分隔开的字符串列表。

SQL>connect strmadmin/strmadminpw@test96; SQL>begin dbms_streams_adm.maintain_schemas( schema_names => 'yekai,xzh2000', source_directory_object => null, destination_directory_object => null, source_database => 'test96.net', destination_database => 'test99.net', perform_actions => true, bi_directiona=> false, include_ddl => true, instantiation => dbms_streams_adm.instantiation_schema_network); end; /

    说明:当perform_actions参数等于true时,就不必在源库与目标库创建上directory对象,source_directory_object/ destination_directory_object为空,perform_actions参数等于false时,必须在源库与目标库创建directory,并为source_directory_object/ destination_directory_object赋值,这时并不执行stream复制配置,它只是在相应的directory中产生了配置复制的脚本;bi_directional参数等于flase,表示schema级的复制是单源复制,它从源库复制yekai、xzh2000模式的改变到到目标库;include_ddl参数表示允许复制yekai、xzh2000这个模式中发生的ddl变化;instantiation参数的值表示通过expdp/impdp初始化目标库的数据时,直接通过network初始化目标库的scn的值;如果在执行maintain_schemas过程时出错,可以按照上节介绍的recover_operation过程来处理,recover_operation过程同样适用maintain_*等过程。

     

0
相关文章