一.概念
1.oracle streams提供了专一的信息共享解决方案。
2.数据库之间,应用程序之间,应用程序和数据库之间,不同版本的数据库,不同操作系统的数据库,不同的数据库比如DB2,sql server之间进行信息共享。
3.在oracle streams中,最小的信息共享单位被称为消息message,一个消息可以在对数据库的修改中被捕获到,也可以从数据库的事件中产生,包括dml,ddl(比如对表和索引的添加等),但是,某些操作不在共享范围之内,比如增加数据文件,启动一个备份或者卸载一个表空间等。
4.oracle streams可以控制要捕获的消息---信息流,信息流传播的方式,以及信息流到达目标端时的使用或者应用模式。
5.orale streams有众多的应用程序,例如消息队列,数据保护,数据仓库加载,数据复制,我们主要学习数据复制。
6.oraclestreams是oracle database 11g 中一个标准且完整的功能,但是oracle database 11g的标准版把同步捕获作为自动捕获数据库修改的唯一方法,所谓的同步捕获就是在数据发生修改的同时就捕获,而不是在修改完成之后再日志中捕获。 在企业版中,异步捕获支持。
二.oracle streams中的信息流
1.oracle streams中的信息流向
捕获 ------ 暂存和传播 ----------消费
首先,oracle streams的捕获进程捕获到消息,然后消息被捕获进程重新格式化并放置到(暂存并插入队列)一个暂存区域,这个区域是一个通常被称为 streams队列 的内存中的数据结构。捕获进程随后将消息发布到streams队列中。streams队列中读取这些消息的进程被称为消费者进程。这些进程需要在streams队列中注册他们接受消息的偏好,即选择要接收哪些消息,这些进程被称为订阅者进程。消费者或订阅者可以是一个streams进程(如应用进程)或者外部应用程序进程。
例如:在streams队列中,本地消费者可以读取消息或者让消息出队,然后处理消息;消息也可以传播到其他系统的某个streams队列,然后由其他的消费者或应用进程处理。
2.负责oraclestreams信息流的三个主要组件
捕获(capture)组件。
暂存(staging)和传播(propagation)组件。
消费组件(consumption)
在oraclestreams的体系结构中,这三个组件都包含一些其他的子组件,进程或者配置需求,在oracle streams复制中,这些组件会自动协作。从而将消息发送到相应的目标。
三.oracle streams体系结构概述
3.1.捕获组件
3.1.1捕获进程是一个数据库后台进程,通常用来创建消息,
异步捕获进程:从重做日志文件提取对数据库所做的修改,进而创建消息。
同步捕获进程:通过实时捕获dml修改来创建消息。
创建的消息被称为 “逻辑修改记录”--logical change records--LCR----以一种特殊的数据格式创建的消息
LCR分为隐式LCR和显式捕获LCR ----------------当消息被自动捕获是,称对应的进程为隐式捕获进程,称创建包含消息中信息的数据库为 源数据库。当消息由用户应用程序创建时,称对应的进程为显式捕获进程。
由异步捕获进程创建的消息被称为 隐式LCR,由一个缓冲队列来为这些消息排队。
由同步捕获进程创建的消息也称作 隐式LCR,但是由一个存储在磁盘上的持续队列来为这些消息排队。
由用户应用陈谷创建的消息称为 显式LCR,这里书里面没有说明,先暂时这样理解。 --存储位置理解为 在创建对象边的缓冲队列。
3.1.2.捕获的内容
如果我们不想捕获所有修改,那么可以指定需要捕获的修改。在streams中,这些指令称为规则,换句话讲,与捕获进程关联的streams规则决定捕获进程需要捕获的修改,这些规则可以自动或者手动创建,可以更改已有的规则或者自定义规则。
3.1.3.捕获的方式
3.1.3.1.基于日志的捕获
利用logminer功能来挖掘数据库重做日志,以捕获数据库所做的修改。 优点:因为是从重做日志信息中捕获,所以只要归档存在,就可以捕获,保证了数据库崩溃或者中间错误时候的可恢复性。
3.1.3.2.本地捕获
捕获进程通常以一个数据库后台进程的形式在源数据库上运行,这称作“本地捕获进程”,它对源数据库来说是本地的,本地捕获进程可以无缝地扫描或挖掘内存中的重做日志缓冲区,联机重做日志甚至是归档日志(当需要时)来捕获对本地数据库的修改。当修改规则符合由捕获规则定义的选择标准的时候,就捕获并将其装换称LCR,然后放入一个内存中称为 stream池额暂存区域,这是本地捕获的默认行为。
3.1.3.3.下游捕获
通过在另一个数据库服务器上运行捕获进程来捕获对源数据库所做的修改,在这种情况下,日志文件除了会写入源数据库服务器外,还会写入远程数据库服务器。oracle streams利用日志传输服务和oracle data guard功能将日志写入远程服务器。远程服务器上的捕获进程从源数据库中挖掘日志,并且将其在在本地暂存。如果远程数据库的应用进程是这些修改的订阅者,那么这些修改可以应用到远程数据库,否则,这些修改会被传播到另一个暂存区域等待处理。
优点:首先,可以将捕获修改的进程从产品数据库卸载并放入到另一个数据库中。 其次,由于使用data guard保护模式可以实现远程写重做日志,因此可以针对具体环境选择一个合适的模式,可以使用一个远程数据库来捕获多个源数据库所做的修改。
3.1.3.4.同步捕获-----只捕获dml操作。
同步捕获是oracle database 11g新增加的功能,同步捕获并不是挖掘重做信息来捕获修改,而是去捕获由dml语句产生的对表的修改。一旦表数据发生变化,同步捕获进程就实时地捕获这个修改或消息并将其转换成一个LCR,随后,这个LCR并不是写入内存中的暂存区域,而是写入磁盘队列。在oracle database 11g中,通不捕获无法捕获由ddl语句长沙市能够的修改。同步捕获更加适合用户复制那些针对少数几个表的低容量DML活动。
3.2.暂存和传播组件
订阅者和消费者需要得到捕获的LCR,oracle streams通过为传播LCR来实现这一功能。
3.2.1.暂存
所有捕获的消息都存储在一个暂存区域中,这个暂存区域是一个内存中的缓冲区,并且也是数据库实例的系统全局区(sga)的一部分。由用户应用程序创建的消息也存储在这个暂存区域中,由同步捕获进程创建的LCR不是存储在内存队列中,而是存储在一个磁盘队列列表中。
直到所有订阅者处理完之后,暂存区域中的消息才消失。订阅者可以读取暂存区域中的内容,进而选择符合要求的信息。订阅者可以是一个应用程序,一个暂存区域,一个不同数据库的应用进程。应用程序可以显示的让暂存区域中的消息出队或者读取这些消息以处理他们。如果这个暂存区域中的订阅者是一个应用进程,那么该应用进程可以会让消息出队并应用它。
3.2.2.传播
使用oracle net中的数据库链接,可以将一个暂存区域中的消息传播到另一个数据库的另一个暂存区域中。streams在选择消息路由的方式时非常灵活。可以在传播时应用规则来选择需要传播到另一个暂存区域中的消息。可以修改已存在的传播规则或者是自定义规则。
在某些情况下,并不要求进行传播。当捕获进程创建消息时,同一个暂存区域的消费者可以让消息出队。在这种情况下,发布者进程和消费者进程都运行于同一个数据库中。
有向网络(Directed Network):oracle streams可以控制消息在网络中传播的方式。在一个数据库中捕获的消息在到达预设的订阅者或目标之前,既可以发布或传播到网络上的其他数据库中,也可以通过网络上的任意其他数据库进行传播。这个功能就称为 有向网络。
即使源数据库和目标数据库没有直接的网络通信,消息也仍然能够通过其他的以及在源数据库和目标数据库之间都有网络通信的中间数据库进行中转。
如上图,数据库a的消息通过不哦数据库B发送到数据库C。
数据库A和C之间可存在多哥数据库,也可以存在多哥目标数据库而不仅仅是数据库C。
当发送消息到多个目标时,源数据库只向中间数据库发送一次消息,然后再由中间数据库将同一消息发送到所有其他的目标,而不是用源数据库发送多次。
中间数据库只是简单的把一个stream 队列的内容转移到另一个streams队列,这称作 “队列转发”(Queue Forwarding)
也可以在中间数据库应用消息,然后使用中间数据库上的捕获进程再次捕获它并将其传播到其他数据库,这称为 应用转发 “Apply Forwarding”
3.3.消费组件
消息从暂存区域出队时会被处理。 应用进程隐式的将消息从暂存区域中取出。如果消息时由应用进程处理并且是被应用到数据库中的对象上,那么该数据库就称为 “目标数据库”。该应用进程在目标数据库上以本地方式运行。
应用程序或进程也可以显式的将消息从暂存区域中取出,该暂存区域相对于用户应用程序可以是本地或远程的。
应用规则可以决定出队并且由目标数据库中应用进程应用的消息。在默认情况下,应用进程会应用捕获的LCR,但是也可以使用自定义的PL/SQL存储过程来截取并处理这些LCR。应用进程还可以使消息从缓冲区队列中出队并将其插入到一个持久队列中以允许其他应用程序处理它。
3.3.1.默认应用进程
默认应用进程在目标数据库上被配置成多个数据库后台进程。默认情况下,如果捕获的lcr是dml和ddl产生的对源数据库进行的修改,那么应用进程会自动应用他们。在对目标数据库应用修改时,应用进程可以检测所有的数据冲突。
在一个异构环境中,可以使用合适的oracle transparent gateway(oracle透明网关)服务将消息发送到远程的非oracle数据库。
3.3.2定制应用进程
定制应用进程在功能上和默认应用进程类似。通过定制可以完全控制应用进程处理LCR的方式。可以自定义PL/SQL存储过程。在oracle streams中,用户创建的存储过程称为“应用处理存储过程”。
应用处理存储过程通常可以应用于所有的LCR,也可以有选择的应用某些lcr,可以定义不同的应用处理程序来处理不同的dml修改。例如,可以为针对同一张表的insert,delete和update操作定义单独的应用处理程序。这样一来,就可以选择忽略所有针对目标数据库中所选数据表的删除语句。也可以将LCR中的delete命令修改为update命令,这样一来,删除语句就被更改为针对目标数据表的更新语句,从而可以更新一个字段。正是由于这种灵活性,可以实现定制的复制数据库来满足独特的业务和法律需求。
3.3.3.冲突检测和解决
通过设计,应用进程在修改应用到数据库时检测数据冲突。当应用进程试图为更新或删除识别数据行时,如果表中的目标行与lcr中的对应数据无法配对,就会发生冲突。LCR包括源行中修改过的列在修改前后的值,并且希望目标行中是修改前的值。如果修改前的值不能配对,就认为发生了数据冲突。在这种情况下,可以根据需要调用一个冲突解决存储过程。oracle提供有很多预先生成的冲突处理存储过程。可以使用提供的冲突处理存储过程或自定义存储过程来解决冲突 以满足业务需求。
如果无法解决冲突或者冲突处理存储过程报出异常,那么应用进程会将整个事务放到一个持久错误队列中。可以在修正数据冲突问题后重新执行错误事务。如果冲突能被其他不需要重新执行错误事务的方法解决,那么也可以根据需要删除错误事务。
3.4.队列
可以将队列看作一个消息的存储位置。应用程序可以将消息发送到队列中或者从队列中提取消息。当一个应用程序需要同其他应用程序或进程通信时,这个应用程序可以将一个消息插入到消息队列中,然后使其他应用程序就能够从队列中提取消息。
oracle streams组件使用队列来交换消息。消息队列可以为不同的进程或应用程序提供一种无故障的异步通信方式。队列支持插入消息到队列中,让消息出队以及传播消息到其他的队列或系统中。
消息包括:信息和内容--载荷两部分。
消息的内容可以是特殊的数据类型或原始数据类型。oracle streams有一个称为ANYDATA的通用数据类型。所有的LCR都必须暂存到ANYDATA队列中。
oracle streams高级队列特性支持使用ANYDATA或其他抽象类型的消息。ANYDATA队列的主要优势是允许应用程序在同一个队列中发送不同类型的消息。一个队列可以通过使用一个或多个表保存在数据库中。
3.5.oracle stream是标签
所有数据库修改的重做信息都包括一个标记或者说是一个标签。按照默认,这个标签的值是null,并且它在重做记录中不占用任何空间。标签字段的数据类型是RAW,大小限制是2000字节。当捕获进程将重做信息转换为LCR时,标签字段将成为这个LCR的一部分。
如果某个独有的数据库生成一个特别的LCR,那么oracle streams可以利用数据库的这个特性进行识别和跟踪。对于配置为双向的或者是多向的复制环境,这种识别是强制性的。如果缺乏这种识别,则会导致消息循环回其最初的源数据库。
在默认情况下,有应用于捕获、传播和应用进程的streams规则来检查标签字段的值。只处理标签字段值为空(null)的LCR,而丢弃值不为空的LCR。当修改应用到目标数据库时,目标数据库上的应用进程将标签字段的值设为16进制的00(0)。因此,由应用程序所执行事务产生的重做信息将会有一个值非空的标签字段。这样一来,一个针对双向复制的捕捉进程(如果存在的话)便会忽略由本地进程所做的此类修改,从而避免循环修改。
也可以使用这种功能暂时挂起对某些动作的复制。可以为会话更改数据库中标签字段的值,进而使得捕获进程忽略在会话中由重做记录产生的所有LCR。然后,需要多目标数据库做同样的操作以保持和源数据库中数据的同步。可以为会话将标签字段的值重置为它原来的值来重做普通复制或者简单的退出会话。
3.6.规则和规则集
Oracle Streams使用规则控制消息的捕获、传播和处理。一个规则是一个数据库对象,例如表或索引。当配置streams组件时,规则将作为一个条件。规则条件类似于sql语句中的where子句。
规则包含:
规则条件:由一个或多个表达式合并而成,返回一个布尔值。
评估上下文:定义了在评估规则条件时可以被规则引用的外部数据。外部数据可以是一个变量、表数据或者包括两者。
动作上下文:这是在评估规则条件时由规则引擎的客户端解释的可选信息。捕获、传播和应用进程都是规则引擎的客户端。
相关的规则合在一起便组成了规则集,一个规则集和一个streams组件相冠梁。
oracle streams支持两种类型的规则集:
正规则集:如果一个正规则集中的评估规则评估为TRUE,streams会在处理时包括这个LCR。
负规则集:如果一个负规则集中的规则评估为TRUE,那么streams会丢弃这个LCR。
可以在一个streams组件中同时包括正规则集和负规则集,这种情况下,负规则集首先被评估。如果被评估为TRUE,那么正规则集会被忽略,因为消息会被丢弃。
***同步进程智能有一个正规则集。
如果在配置streams复制时没有创建规则合规则集,那么oracle会自动生成他们,将他们称作系统生成的规则合规则集。对于大多数简单的复制环境,这些系统生成的规则合规则集已经足够。可以自定义规则合规则集,也可以更改系统生成的规则合规则集来满足需求。
3.7.实例化
在从源数据库复制表到目标数据库时,目标数据库需要包含对应表的副本。如果目标数据库中没有包含这个表,那么必须在源数据库中创建它或者对表进行实例化。表的实例化方法有很多。根据具体的环境和需求,可以使用CTAS(create table as select),data pump、导入/导出,便携式表空间、分割的镜像拷贝或恢复管理器(recovery manager rman)。
首先,必须在源数据库中准备好要实例化的数据表。在复制配置过程中,oracle会自动准备好要实例化的数据表。也可以使用提供的存储过程来准备要实例化的数据表。在这一点上,oracle将记录下数据库的系统修改编号(system change number,scn)并在一个内部的streams数据字典中填充数据库的全局名称、表的名称及其对象编号、列名和列编号等。然后,如果目标数据库不存在该表,那么必须使用源数据库的内容创建它。最后,将目标表的实例化scn设置为源数据库的scn。data pump和导入导出工具在导入数据时设置目标数据库中标的实例化scn。也可以使用所提供的额一个存储过程来设置目标数据库中表的实例化scn。
实例化scn控制着包含数据库修改的哪个LCR要通过应用进程被应用到目标数据库以及哪个LCR被忽略。如果在LCR中源数据表的提交SCN比目标数据库中表的实例化scn大,那么应用进程会对表应用修改。否则,会忽略LCR。在忽略这种lcr时,oracle不会报告任何警告或错误信息。
3.8.LogMiner数据字典
oracle数据库进程使用数据库数据字典来映射对象编号、对象版本信息以及对应表名的内部列编号、列名和列对象数据。数据字典总是与当前数据库配置同步。
虽然从捕获进程可以读到重做日志文件或者归档日志文件中的重做信息,但是数据库数据字典的当前信息可能并不会和这些重做信息一致,所以streams捕获进程需要单独的数据字典。这些信息可能会首先生成,然后在捕获进程扫描日志文件之前数据库数据字典可能就已经做出了改变。
捕获进程使用的数据字典称作LogMiner数据字典。oracle在第一个捕获进程创建时从重做日志中提取数据库数据字典信息。捕获进程第一次启动后,开始从重做日志中读这个数据字典的信息并创建logminer数据字典。这个lominer数据字典的内容保存在内部的logminer表中。
源数据库可以有多个logminer数据字典。多个捕获进程可以共享一个通用的logminer数据字典,或者每一个进程也可以有单独的logminer数据字典。
注意:同步捕获进程没有使用logminer数据字典。
3.9.streams数据字典
传播和应用进程与捕获进程类似,也需要单独的数据字典以跟踪源数据库汇总的对象名和对象编号。当源数据库准备需要实例化的对象时,和实例化相关的信息以及对象的细节将一同写入重做日志。捕获进程读取这些信息并且在数据库运行时将这些信息加入到streams数据字典中。本地捕获进程的streams数据字典在源数据库汇总,而下游捕获进程的streams数据字典在下游数据库中。在准备对象以实例化时请更新streams数据字典。
传播进程在评估规则以处理捕获的LCR时,需要源数据库streams数据字典中的对象映射信息。oracle 会自动将一个本地的多版本streams数据字典加入到配置了传播进程的数据库中。
类似的,应用进程在评估规则以处理捕获的LCR时,也需要源数据库streams数据字典中的对象映射信息。oracle 会自动将一个本地的多版本streams数据字典加入到配置了应用进程的数据库中。
3.10.NOLOGGING操作和UNRECOVERABLE操作
oracle streams从重做日志中捕获数据库修改。当dml操作以nologging方式执行时,不会产生重做日志。SQL*加载器以UNRECOVERABLEF方式进行直接路径加载时,也会禁止生成重做日志。在这些情况下,由于重做日志中缺乏记录,dml修改不会被捕获为了成功复制这些修改,需要避免使用nologing和unrecoverable操作。
为了保证正确记录表修改日志,可以在表空间级别或数据库几倍蛇者forcelogging。一旦设置,oracle就可以自动为所有的nologging操作和unrecoverable操作生成重做日志信息。
如果因为性能原因而必须在源数据库上使用noogging操作和unrecoverable操作,那么需要在目标数据库上进行同样的操作以保证数据同步。否则,目标数据库上的数据匹配错误会导致后续dml操作中的应用进程发布错误。
3.11.补充日志
数据库修改以及所需的信息都记录在重做日志中,这是为了在发生实例错误或介质错误时执行数据库活肤。oracle streams使用同样的重做日志来创建应用到目标数据库的消息(LCR)。重做信息中包含源数据库中发生修改的列的值。但是这些信息有时候不足以正确识别目标表中的行来应用同样的修改。
补充日志是一个在重做日志中记录附加列数据的进程。捕获进程将整个附加信息插入到LCR中。应用进程使用整个附加信息来正确识别需要应用修改的行。
如果需要应用程序在oracle数据库外保证数据完整性,并且表没有主键或唯一约束,那么就有必要配置足够的补充日志。有时甚至需要对表中所有列都做补充日志。
****补充日志总是在源数据库配置,与本地捕获进程或者下游捕获进程无关。
补充日志可以在数据库级别偶表级别配置。在数据库级别,可以通过配置它在重做日志中记录附加的信息来识别重做日志中的行,也可以通过配置它记录某种特殊类型的列在修改前后的值,例如主键列、唯一索引列、外键列或者表中所有的列。
如果一个表没有主键约束或唯一性索引,那么就有必要为一些列配置补充日志。
在表级别,补充日志创建单独的日志组,其中包括每个表的列名。这种日志可以是有条件的或者是无条件的。有条件的补充日志只有在指定的列中有列发生更新时,才会在重做日志中记录下所有这些列修改前的镜像。无条件的补充日志则不管指定的列是否有更新,都会在重做日志中记录下所有这些列修改前的镜像。有时这称作“随时日志”,所有用于原始数据识别的列都必须使用无条件的补充日志。
****同步捕获进程不需要补充日志信息。
3.12.逻辑修改记录
捕获进程从日志文件中捕获到数据库的修改信息后做了格式转换。格式转换后的消息称作逻辑修改记录,表示数据库的修改。
捕获进程可以创建两种LCR:
行LCR 每一个LCR(有时候也称作DML LCR)表示对单个行所做的修改。此外,对于一些数据类型为LOGN,LONG RAW或者以CLOB类型存储的XML类型的单个列的修改,可以存在多个LCR。而且单个DML语句可以影响到多行,导致创建多个LCR。
DDLLCR 这个LCR代表由一个ddl命令产生的修改。
这些LCR包含足够的信息以将改变应用到目标数据库中。此外,为了审计和跟踪,还可以在LCR中包含额外的信息。索然LCR的数据格式由oracle sreams内部使用,但是一些存储过程也可以访问和修改包含在LCR中的信息。
3.13.表数据的比较
oracle database 11g包含存储过程以在分布式的复制环境中比较和同步(合并)共享表中的数据。DBMS_COMPARSON包(package)中包含的存储过程可以在没有其他应用程序介入的情况下比较表数据。这些存储过程既可以比较整个表中的数据,也可以比较某个数据子集或数据范围内的数据。比较可以周期性的进行或者随时调用。可以在行级别或者表级别检查数据的一致性。对于识别出的差异,可以进行查看。这些数据差异可能缘于不完整的事务,不可恢复的错误等。找到数据差异后,所提供的的存储过程可以合并差异并且确认表数据不匹配错误已经解决。
小结:Oracle Streams是一个信息共享解决方案,提供了一个健壮且灵活的基础设施以管理oracle数据库和非oracle数据库之间的信息流。使用重做信息,oracle streams可以在网络中无缝的捕获并且轻松辅助数据库的修改。用户捕获进程、传播进程和应用进程的streasm规则提供了定制功能,可以根据业务需求控制消息的选择、路由和处理。使用同步捕获功能,可以使用oracle database 11g标准版冲从数据库中复制数据。下游捕获配置可以将日志挖掘进程卸载到其他的数据库来减少产品系统的负载。oracle streams是一个整合到oracle数据库软件的特性。