5、ANYDATA队列和用户消息

  Streams 中ANYDATA队列中可以存放不同类型的用户消息,以ANYDATA做为载体,应用就可以将不同类型的消息放到一个队列里,应用也可以将其出队(或消息客户端/用户应用/apply进程)。

  Streams 包括高级队列(Advanced Queuing)的特性,支持消息队列的所有标准特性,包括queues, publish and subscribe, content-based routing, internet propagation, transformations, and gateways to other messaging subsystems。

  使用静态函数Convert data_type几乎可以将所有类型都打包为ANYDATA,

6、缓存消息(Buffered Messaging)和Streams客户端

  缓存消息支持用户从buffered queue中入队和出队消息。传播进程能够在buffered queue中传送缓存消息。使用缓存消息替换磁盘中的队列表能够提高性能。

    提示:要使用缓存消息,则数据库初始化参数compatible的值不能低于10.2.0.1

  下面简要描述一下缓存消息与streams客户端之间的交互:

  • 与capture进程:被capture进程捕获入队的缓存消息只能被apply进程出队。
  • 与propagation进程:只要符合其传播规则,propagagion进程能够传播源队列中所有消息。这些消息即可存储于buffered queue,也可以存储于queue table。
  • 与apply进程:apply进程能够出队并应用buffered queue中的消息。要出队buffered queue中被capture进程入队的消息,apply进程必须配置apply_captured参数值为true。要出队buffered queue中被用户应用入队的消息,apply进程必须配置apply_captured参数值为false。
  • 与消息客户端:不被支持。
7、队列与RAC

  Streams 同样支持RAC环境的数据库。不过注意RAC环境中一个buffered queue只能在一个实例中,这是因为buffered queue是与系统sga相关联的。

  Streams 进程和job支持主实例和次实例对queue tables做描述,如果你应用这种描述,则当主实例不可用时,次实例可暂时接管这部分queue tables,直到主实例恢复服务,你可以通过DBMS_AQ_ADM.ALTER_QUEUE_TABLE过程指定主实例和次实例。

  Capture 进程和apply进程在队列属主实例上启动,propagation进程稍有不同,如果队列属主实例不可用,则其属主自动转换到集群中的其它实例上。队列到队列的传播会自动连接目标队列的属主实例。

  队列到dblink的传播不会使用服务,因此为保证传播任务连接到正确的实例,需要手工配置源数据库到目标数据库的数据库链。

8、Commit-Time队列

  你可以控制User-Enqueued Messages在队列中浏览和出队的顺序。消息在队列中的顺序基于其队列表,因此你可以在创建队列表时为消息指定好顺序。实际上,队列中的顺序是由DBMS_AQADM.CREATE_QUEUE_TABLE过程的sort_list参数控制的。10gR2引入了一种commit-time队列。Commit-time队列中的消息按照scn排序。

  Commit-time 的顺序是为队列表指定的,使用这种队列表的队列就被称为:commit-time队列,如果DBMS_AQADM.CREATE_QUEUE_TABLE过程的sort_list参数指定为comiit_time,则队列表使用commit-time顺序。对于10gR2,DBMS_STREAMS_ADM.SET_UP_QUEUE的sort_list参数默认值就是commit_time,之前版本默认值为enq_time。

9、Streams分段与传播架构

  本节描述buffered queues,propagation jobs和secure queues,以及它们在Streams中如何工作。另外,本节还将描述transactional queues如何处理捕获消息和User-Enqueued Messages,以及传播捕获消息所需的Streams数据字典的内容。

A 、Streams pool

  Streams pool 也是SGA中的一部分。用来存放Buffered queue消息以及capture进程/apply进程所需的内存。一般streams pool初始化会在下列几种操作发生时:

  • 消息入队。Data Pump export/import。
  • Capture 进程启动
  • Apply 进程启动

  Streams pool 的大小有以下几种设置方式(注意顺序,如此排列也是有道理的):

  • BY SGA_TARGET :指设置SGA_TARGET初始化参数为非0值,这样系统会根据需要自动调整SGA内存区的分配。
  • BY USER :指设置STREAMS_POOL_SIZE初始化参数为非0值(SGA_TARGET值为0),这样ORACLE启动时就会分配你指定的大小给Streams pool。提示:建议不小于200M。
  • BY DEFAULT :如果SGA_TARGET和STREAMS_POOL_SIZE两参数值均为0,则streams在初始化时会自动从buffer cache中截取10%的内存为Streams_pool_size参数的值。
    提示:如果Streams pool未初始化,则触发ORA-00832错误,要解决此类问题,首先要确保SGA中有足够的空闲内存,如果必要,重新设置SGA_MAX_SIZE初始化参数增加SGA大小,然后修改SGA_TARGET或STREAMS_POOL_SIZE初始化参数的值。

B 、Buffered queues

  一个Buffered queue可能分成多个部分存在于Streams pool和磁盘。如果Streams pool size不是自动管理的话,建议至少为每个bufferd queue增加10m内存给Streams pool。Buffered queue能够提高性能,不过如果包含buffered queue信息的实例shutdown normal/abort的话,这部分数据就会丢失,实例恢复后,Streams会自动修复。

  Buffered queue 中的消息如果在一定时间内未出队或无足够内存空间存的话,就有可能被分隔成多份存入队列表,从内存中分隔出来的消息会保存在AQ$_队列名称_p表中,至于这些消息对应哪些propagation/apply进程的信息,则存储于AQ$_队列名称_d表中。

  捕获消息总会存入buffered queue,不过user-enqueued LCR/non-LCR messages则可能不会存入buffered queue。对于user-enqueued message,入队时操作指定消息是存入buffered queue还是存入persistent queue。Persistent queue只会将消息保存在硬盘上。消息究竟是存储于buffered queue还是persitent queue要看BMS_AQ.ENOUEUE过程的enqueue_options参数的属性delivery_mode的值,如果delivery_mode的值是PERSISTENT,则消息存入persistent queue,如果该值是BUFFERED,则消息存入buffered queue。

C 、Propagation Jobs

  传播任务内部还是使用DBMS_JOB来配置,因此这部分没啥说的,大家应该都挺熟,下面说一下会创建传播任务的几个过程:

  • DBMS_STREAMS_ADM . ADD_GLOBAL_PROPAGATION_RULES
  • DBMS_STREAMS_ADM . ADD_SCHEMA_PROPAGATION_RULES
  • DBMS_STREAMS_ADM . ADD_TABLE_PROPAGATION_RULES
  • DBMS_STREAMS_ADM . ADD_SUBSET_PROPAGATION_RULE
  • DBMS_PROPAGATION_ADM . CREATE_PROPAGATION

1).Propagation scheduling and Streams Propagations

  传播调度(Propagation scheduling)指定传播任务传播消息的频率。第一个queue-to-queue的传播都会拥有各自的调度,不过queue-to-dblink的传播共用同一个调度。

  默认情况下调度有下列属性:

  • 开始时间为:sysdate
  • Duration 为空,表示无限
  • Next time 为空,表示上次传播结束后,新传播马上开始
  • Latency 为3秒,指queue清空后等待重新提交的最大等待时间。

2).Propagation job and RESTRICTED SESSION

  当通过startup restrict语句进入受限模式连接时,传播任务不会执行传播,直到restricted session被disable。

  当通过alter system enable restricted session语句进入受限模式连接时,正在运行的传播任务会继续运行直接到结束,不过新的传播任务不会再启动,直到restricted session被disable。

D 、Transactional and Nontransactional Queues

  Transactional queue 就是user-enqueued messages分组打包到一个集合队列被一个事务应用,apply进程是在应用User-Enqueued Messages组之后才提交。DBMS_STREAMS_ADM.SET_UP_QUEUE过程总会创建transactional queue。

  Nontransactional queue 是指每个User-Enqueued Messages拥有不同的事务,apply进程应用完任意一个User-Enqueued Message后即执行提交。

  基本上对于User-Enqueued Messages,Transactional/Nontransactional queue之间不同才显的较为重要,因为apply进程应用捕获消息时都会是在事务模式(即以源库执行的方式)下执行。

E 、Streams Data Dictionary for Propagations

  源端数据库的数据库对象准备初始化的时候,Streams数据字典就会自动记录数据库中capture进程捕获的修改。Streams数据字典实际上是源端数据库主数据字典某些信息的多版本复制,Streams数据字典映射源端对象编码,对象的版本信息以及内部列号为表名,列名和列类型,通过这种方式来保持捕获消息的最小化(因为数字通常比名字要小)。

  为确保映射信息可用于传播,源库中的streams数据字典映射信息需要目标库的评估规则,Oracle自动在需要复制的数据库中维护多版本streams 数据字典。

  Streams 数据字典信息包括的队列中的内部消息可能不会被传播,是否被传播还是依赖于传播的规则集。比如说当传播碰到Streams数据字典信息包含的表时,传播规则先会评估部分信息包括源库名,表名以及表属主等信息,如果部分规则评估检查通过,则这个表的数据字典信息就会被复制。

  当streams数据字典信息复制到目标队列,这部分就会成为streams数据字典信息的一部分,做为附加值入队到目标队列。因此,传播读到目标队列在directed networks配置环境中能够直接发送LCRs而不需要等待Streams数据字典,通过这种方式,源库streams数据字典总能 正确 反映其关联的数据库对象的状态 。