4. 应用DDL修改


4.1. APPLY 进程忽略的DDL语句


APPLY 应用不支持下列类型的DDL语句:


ALTER MATERIALIZED VIEW


ALTER MATERIALIZED VIEW LOG


CREATE DATABASE LINK


CREATE SCHEMA AUTHORIZATION


CREATE MATERIALIZED VIEW


CREATE MATERIALIZED VIEW LOG


DROP DATABASE LINK


DROP MATERIALIZED VIEW


DROP MATERIALIZED VIEW LOG


RENAME


如果apply进程在应用DDL LCR时发现不支持的操作,会自动忽略该LCR并记录一条信息到apply进程的trace文件。


注意:


Alter objectType objectName rename 语句是能够被apply应用支持的,比如alter table rename之类的。Snapshot是materialized view的同义词,因此snapshot相关的语句也不会被apply应用支持。


4.2. Streams 复制环境中的数据结构


数据结构不仅包含数据文件、表空间、回滚段之类物理结构,还有比如表结构等等逻辑结构。捕获的DDL要在目标端完全应用,要么确保源和目标端的结构一致,要么在源端执行sql语句时不要包含目标端没有的对象。


比如说,一项对表做修改的DDL要想在目标端成功应用,需要考虑下列诸项因素:


Create table 的存储参数相同


如果指定了回滚段,表空间等项,则该表空间/回滚段必须确实存在于目标端。


如果指定了分区信息,则分区在目标端也必须有效。


注意DDL应用时,执行ddl的shcema必须已经存在于目标端数据库。


4.3. 系统产生的对象名称


应尽可能避免系统产生的对象名称。因为源端捕获的实际还是ddl语句,这样在目标端应用后,如果是由系统自动生成名称,则源端和目标端名称有可能会不一致,这就有可能导致后续应用的一些问题。


比如说源端执行这样的语句:


CREATE TABLE tbl (n1 NUMBER NOT NULL);


则系统会自动创建一个not null的约束,假设源端名称为定义为sys_000115,目标端应用create table语句时,可能为该约束创建一个非sys_000115的名字(毕竟源端与目标端并非一模一样),当你再执行删除该约束时:


Alter table tbl drop constraint sys_000115;


源端可以正确执行,但目标端在应用该语句时就有可能报找不到sys_000115对象的错误,正确的方式,应该是在创建时指定名称,比如:


Create table tbl (n1 number constraint ck_tbl_nlnull not null);


4.4. CREATE TABLE AS SELECT 语句的执行


应用create table as select语句时,apply进程执行如下两个步骤:


目标端执行CREATE TABLE AS SELECT语句,不过只创建表并不生成数据。如果失败则apply进程返回错误信息,否则继续执行下一步。


插入数据。注意这一步实际插入的记录可能会受到capture/propagation/apply进程的自定义规则影响,实际插入记录有可能与源端不同。


5. 触发器属性


你可以通过DBMS_DDL.SET_TRIGGER_FIRING_PROPERTY过程控制DML/DDL触发器的触发,该过程控制触发器是否只触发一次。


如果该过程的fire once参数设置为true(默认情况下该参数即是true,你可以通过DBMS_DLL.IS_TRIGGER_FIRE_ONCE函数检查触发器的触发属性设置),下列情况不会触发触发器。


相关更新由apply进程产生。


执行DBMS_APPLY_ADM.EXECUTE_ERROR/EXECUTE_ALL_ERRORS过程产生的修改。


举个例子,Schema:hr中创建触发器update_job_history,当employees表中job_id或department_id被更新时自动插入记录到job_history表,当前streams复制环境如下:


dbs1.net 源端capture进程同时捕获两张表的修改


Propagation 传播修改到目标端dbs2.net


Apply 进程在目标端应用修改


Update_job_history 触发器存在于源端和目标端。


如果目标端dbs2.net中update_job_history触发属性不是fire once的话,实际操作如下:


源端dbs1.net中employees.job_id被修改


Update_job_history 被触发,新记录插入到job_history表


源端的capture进程同时捕获到employees和job_history的修改


修改被传播到目标端dbs2.net


目标端应用这两表的修改


目标端应用employees表修改时update_job_history触发器再次被触发,又有记录被插入job_history表


由上可知,job_history中实际是产生了重复记录了的,多数情况下我们可能是不希望产生这种状况,如果我们设置update_job_history的触发属性为fire once(或者在创建触发器时指定on schema子句),则dbs2.net端就不会再被触发了。


6. APPLY 进程支持的数据类型


下列数据类型可被apply进程支持:


VARCHAR2


NVARCHAR2


NUMBER


LONG


DATE


BINARY_FLOAT


BINARY_DOUBLE


TIMESTAMP


TIMESTAMP WITH TIME ZONE


TIMESTAMP WITH LOCAL TIME ZONE


INTERVAL YEAR TO MONTH


INTERVAL DAY TO SECOND


RAW


LONG RAW


CHAR


NCHAR


CLOB


NCLOB


BLOB


UROWID


不支持的类型有:BFILE, ROWID, and user-defined type (including object types, REFs, varrays, nested tables, and Oracle-supplied types)等。另外,apply进程不支持transparent data加密过的数据,不管加密数据是什么类型。


7. APPLY 进程与受限连接


如果以startup restrict模式启动数据库的话,apply进程就不会被启动。如果是以alter system enable restricted session语句将数据库置为restrict模式的话,对于当前正在运行的apply进程不会有影响,但不会再有新的apply进程启动,直到disable restricte。


8. APPLY 进程与RAC


RAC 环境下apply进程是与实例绑定的,即各实例管理各自的apply进程,如果某个apply进程因某种原因不可用的话,队列ownership自动转换至集群中其它实例。同时apply进程也会随着队列转移至相应实例。另外,激活状态的apply进程所在实例不可用的话,apply进程会自动在新实例上启动,而未激活状态的apply进程所在实例不可用的话,apply进程在新实例中仍然保持未激活状态。


数据字典DBA_QUEUE_TABLES中记录了队列对应的实例信息,另外在RAC环境中,apply coordinator进程,以及其对应的apply reader server和apply servers运行在相同实例上。


提示:


什么是 Reader Server :并行执行服务,capture进程的一部分,用来读取redolog并定位其范围。


什么是 Apply Servers :apply进程的一部分,包含一个或多个并行执行服务,用于应用LCRs或发送其至适当的apply handlers。


什么是 Apply Coordinator Process :做为apply进程的一部分同属oracle后台进程,用于从Reader Server中获取事务并发送给Apply Servers。



oracle视频教程请关注:http://u.youku.com/user_video/id_UMzAzMjkxMjE2.html