本节主要描述传播的工作流程,以及一些相关的特性(处理逻辑),内容同样枯燥,但三思认为有阅读的价值。在整个streams复制环境中,propagation进程负责将源端的修改队列复制到目标数据库。

1、LCR分段

  Streams 通过队列分段传递messages。ANYDATA类型的队列能用来分段传递几乎所有类型的消息,这种类型的队列被定义为:ANADATA QUEUE。注意一个队列中只能存储一种指定类型的消息,STREAMS默认总是使用ANYDATA QUEUE。

  Streams 中两种消息类型可被封装为ANADATA对象置入ANADATA queue:LCR和User-enqueued messages。LCR前面介绍捕获的时候讲过了,这里就不提了。User-Enqueued Messages其实类似于LCR,只不过其中的消息并非oracle自动捕获和生成,而是由用户根据oracle的一些规则自己生成的消息(oracle号称streams能够实现跨数据库类型的复制,其根源就在于支持User-Enqueued Messages)。

  分段传递的LCR存储于staging area。在streams中,staging area就位于sga中的ANYDATA队列用来存储rowLCRs/DDL LCRs以及其它类型的messages。

  Staged LCRs 即可被propagation进程复制到远端,也可被apply进程/消息客户端或用户进程直接应用(某些特殊的staged LCR甚至可同时被传播和应用)。apply进程应用之后会将消息隐式出队,不过消息客户端或用户名进程需要显式地出队。如果你配置了传播或发送,那即使消息被应用过,它也仍然会保存在队列中。

2、LCR传播

  在streams复制环境中,propagation进程从 源端队列 (source queue) 中复制LCRs到 目标端队列 (destination queue) ,如图:

  实际上传播的过程非常灵活,比如上图中这个过程即可以一对多也可以多对一甚至多对多。对于已经propagated或applied的LCRs,如果你期望能将其继续传播至其它队列,甚至可以将其继续保持在源端队列中。

  在传播阶段,你可以创建/修改/删除一条传播,也可以通过定义rule控制哪些消息被传播。消息队列的属主即传播消息者,因此我们也必须给其足够的权限去执行传播,包括:

  • EXECUTE privilege on the rule sets used by the propagation
  • EXECUTE privilege on all custom rule-based transformation functions used in the rule sets
  • Enqueue privilege on the destination queue if the destination queue is in the same database
3、ANYDATA Queue入队和出队

  Streams 支持两种消息入队,分别是capture进程自动捕获的消息和User-Enqueued Messages,不同类型消息入队方式也不同:

  A>.  捕获进程将捕获消息自动入队。

  B>.  用户队列类型由用户打包入队,用户消息可能是LCRs也可以是其它类型。被用户打包入队的消息被称为user-enqueued message。

 

  消息出队也有两种方式:

  A>. Apply 进程会自动将消息出队(不管是捕获消息或User-Enqueued Messages)。如果消息包含LCR,apply进程即可以直接应用,也可以调用用户指定的过程应用,如果不包括LCR,则apply进程需要调用用户指定的过程(称为message handler)处理。另外,消息出队后又被Streams提供的DBMS_APPLY_ADM.SET_ENQUEUE_DESTINATION过程入队的,也是User-Enqueued Messages。

  B>.  用户应用显式出队。由于用户的应用可能不使用Streams消息客户端,因此无法处理capture进程入队的消息,capture进程入队的消息出队还是得由apply进程操作。

  补充知识:消息客户端(Messaging Clients)

  用户或者应用调用消息客户端来出队User-Enqueued Messages。

4、消息传播

  A 、队列到队列的传播

  一个传播可以基于队列到队列,或者队列到数据库链。队列到队列的传播拥有自己的propagation job实施传播,因为每个propagation job都拥有自已的传播调度,能够实现分别管理,即使多个队列到队列和传播进程使用相同的数据库链,你也可以enable/disable/set任意队列传播的传播调度。

    提示:

    要使用队列到队列的传播,复制环境各数据库中compatible参数值不能低于10.2.0.1

  B 、队列间的消息传播

  Streams 环境中可以配置两队列间的消息传播,两队列可以处于不同的数据库,Streams通过job来传播消息。传播总是在两个队列间进行,当然一个队列也可以同时进行多次传播(即向多个目标队列传播),一个队列也可以接收多个不同队列发来的消息。不过在指定的源队列和目标队列间只能有一个传播,同样,单个队列即可做为某次传播的目标队列,也可做源队列。一次传播即可以复制源队列中所有消息到目标队列(即前面说的队列到队列的传播),也可以复制某部分消息,这可以通过设置rule来控制。需要注意的是复制环境配置中tag的设置,应避免产生循环修改。

  C 、传播规则

  传播中的消息被传播或丢弃是基于我们在rule中的定义。对于定义的rule可以置于肯定规则集(positive rule set)也可置于否定规则集(negative rule set)。

  比如某条消息符合某个定义的rule,并且该rule在肯定规则集中,则传播进程就会复制这条消息。如果该rule在否定规则集,则传播进程自动丢弃这项修改。注意,如果一个rule同时存在于肯定和否定规则集,Strema优先考虑否定规则集。

  D 、确保消息发送

  User-Enqueued Messages 传播至目标队列并成功提交后表示传播成功。捕获消息(captured message)当下列两项操作完成时表示传播成功:

  • 消息被所有相关应用进程处理
  • 消息成功传播至所有相关目标队列

  当消息成功在两个ANYDATA队列间传播后,目标队列响应一条成功传播的信息,如果源队列被配置为向多个目标队列传播,则消息会继续保持在源队列,直到收到所有目标队列发送的成功传播的信息,然后源队列就能删除这条消息了。

  这个机制保证消息从源端传播到目标端队列,不过,某些情况下,这种机制也会造成源端队列持续增加以至超出最佳大小,占用更多sga内存和更多的硬盘空间,通常下列两种情况会导致源端队列增长:

  • 某些原因导致消息不能被传播到目标队列(比如网络中断),则消息就会保持在源端队列直到目标队列可用。
  • 目标队列响应过慢,特别是一对多的时候,只要有任意一个目标队列响应较慢,整个源队列都会受到影响,这种情况下建议多创建几个capture进程,分散源队列与目标队列的对应,这样响应较快的目标队列对应的源队列能尽快释放,减轻传播的压力。

  E 、发送二进制文件

  由于支持bfile类型,因此Streams还可以传播二进制文件。过程大概是这样,将bfile类型的列置入大负荷消息(message payload),然后复制该消息到远端队列。消息被传播后在成功提交前含bfile数据的大负荷消息也被传送。注意bfile所在的目录对象和文件名等信息会被保持,因此需要保证目标端目录对象实际指向的有效性(实际指向的目录可以与源端不同)。

  F 、定向网络

  定义网络(Directed Networks)很有意思,官方定义是指传播消息在抵达目标数据库之前跨越一个或多个中转服务器(Intermediate Databases )。如图所示:

  使用定向网络的优势在于当源数据库与目标数据库间没有物理连接时,借助中转服务器,将消息首先传播至中转服务器,然后再由中转服务器处理(或不处理)后发送到目标服务器,同时变相提高了源库安全性,减轻了源数据库的负担,当然如果中转服务器down掉的话,整个streams环境也将停止。

  两个名词:队列转发和应用转发

  什么是队列转发(Queue forwarding)

  表示消息接收到后马上转发,消息属主仍然是源数据库。

  什么是应用转发(Apply forwarding)

  表示消息接收到中转服务器后首先被apply进程应用,然后再被capture进程捕获,然后再继续传播。消息属主发生改变,此时消息队列可以讲与源数据库已无关系,中转服务器成为了新的队列源服务器。

  队列转发与应用转发的区别:

  • 对于队列转发,消息虽然跨跃中转服务器但并没有发生修改(默认情况下),而应用转发则要复杂一些,由于消息已经被应用并重新捕获,因此这中间可能做了很多转换,比如修改了其转发路径或者过滤了某些修改操作等等都是有可能的。
  • 对于队列转发,目标数据库必须有多个apply进程分别处理不同来源数据库的消息。而应用转发需要的apply进程就会少一些,必须对于目标数据库来说,源数据库数量减少了。
  • 对于队列转发,中转服务器必须是独立的。而应用转发则无此限制,你甚至可以理解为中转服务器就是源服务器。

  队列转发的优势:

  • 性能有优势,因此捕获只进行一次,同样传播也有可能更快,必须少了应用和再捕获的过程。
  • 更容易获取消息初始来源
  • 由于消息间信赖关系不强,因此应用并行度可以更高。
  • 如果中转服务器宕机,你可以在捕获端重置start SCN,重新配置捕获、传播和应用。而应用转发需要做的工作就会更多一些,因为一旦应用转发的中转服务器宕机,则相当于源数据库没有了,有可能想重置捕获进程都无从操作。

  应用转发的优势:

  • 对于多源的复制环境,应用转发可能更有利于streams复制环境的搭建,多数的操作都可以放到中转服务器上进行,源端和目标端相对只要做好capture和apply就可以。
  • 对于大型的streams复制环境,应用转发更易于管理和监控,中转服务器中至少有一个apply进程针对源数据库,相当于捕获和应用是一对一。