天天看點

手動建立規則方式建立stream環境

删除strmadmin 使用者,為了幹淨的删除stream的規則等對象:

drop user strmadmin cascade;

源庫建立strmadmin使用者,并授權.

create user strmadmin identified by strmadmin default tablespace tbs_stream temporary tablespace temp;

grant connect,resource,dba,aq_administrator_role to strmadmin;

目标庫建立strmadmin使用者,并授權.

授權Stream管理使用者 :

begin

dbms_streams_auth.grant_admin_privilege(grantee =>'strmadmin',grant_privileges => true);

end;

 --建立資料庫鍊

 切換回source資料庫,以streams的操作使用者stradmin連接配接  ,建立隊列

 create database link klir connect to strmadmin identified by strmadmin using 'klir';

 exec dbms_streams_adm.set_up_queue(); 

 切換到target資料庫,以streams的操作使用者stradmin連接配接 ,建立隊列

  create database link lirhz connect to strmadmin identified by strmadmin using 'lirhz';

  exec dbms_streams_adm.set_up_queue();

手動建立傳播規則和傳播程序:

先建立一個傳播程序的規則集:

sour> begin

dbms_rule_adm.create_rule_set(

rule_set_name => 'strmadmin.propagation_rules',

evaluation_context => 'sys.streams$_evaluation_context');

建立規則集後,會在(dba_rulesets、dba_rule_sets)表中建立propagation_rules規則。

建立傳播的dml規則。

dbms_rule_adm.create_rule(

rule_name => 'strmadmin.member_pro_dml',

condition => ':dml.get_object_owner()=''TEST02'' AND ' ||

' :dml.is_null_tag() =''Y'' AND '||

' :dml.get_source_database_name()= ''LIRHZ'' ');

寫入表:  dba_rules

建立傳播的ddl規則。

   dbms_rule_adm.create_rule(

   rule_name => 'strmadmin.member_pro_ddl',

   condition => '(:ddl.get_object_owner()=''TEST02'' OR ' ||

   ' :ddl.get_base_table_owner() =''TEST02'') AND ' ||

   ' :ddl.is_null_tag() =''Y'' AND '||

   ' :ddl.get_source_database_name()= ''LIRHZ'' ');

把dml、ddl規則添加到規則集中

   dbms_rule_adm.add_rule(

   rule_name => 'strmadmin.member_pro_dml',

   rule_set_name => 'strmadmin.propagation_rules');

把ddl規則添加到規則集合中 ,

建立propagation程序。

   dbms_propagation_adm.create_propagation(

   propagation_name => 'pri_to_klir',

   source_queue => 'strmadmin.streams_queue',

   destination_queue => 'strmadmin.streams_queue',

   destination_dblink => 'klir',

   end;

建立capture程序部分。

手動建立捕獲規則和捕獲程序:

建立規則集

   dbms_rule_adm.create_rule_set(

   rule_set_name => 'strmadmin.capture_rules',

   evaluation_context => 'sys.streams$_evaluation_context');

建立dml規則

   rule_name => 'strmadmin.member_cap_dml',

   condition => ':dml.get_object_owner()=''TEST02'' AND ' ||

   ' :dml.is_null_tag() =''Y'' AND '||

   ' :dml.get_source_database_name()= ''LIRHZ'' ');

建立ddl規則   

   rule_name => 'strmadmin.member_cap_ddl',

加入規則集。

   rule_set_name => 'strmadmin.capture_rules');

建立捕獲程序

 begin

   dbms_capture_adm.create_capture(

   queue_name => 'strmadmin.streams_queue',

   capture_name => 'lirhz_capture',

   rule_set_name => 'strmadmin.capture_rules');   使用捕獲的規則集。

源庫建立的捕獲傳播規則

SQL>  select RULE_NAME,RULE_CONDITION from dba_rules where rule_owner='STRMADMIN';

RULE_NAME                      RULE_CONDITION

------------------------------ --------------------------------------------------------------------------------

MEMBER_CAP_DDL                 (:ddl.get_object_owner()='TEST02' OR  :ddl.get_base_table_owner() ='TEST02') AND

MEMBER_CAP_DML                 :dml.get_object_owner()='TEST02' AND  :dml.is_null_tag() ='Y' AND  :dml.get_sour

MEMBER_PRO_DDL                 (:ddl.get_object_owner()='TEST02' OR  :ddl.get_base_table_owner() ='TEST02') AND

MEMBER_PRO_DML                 :dml.get_object_owner()='TEST02' AND  :dml.is_null_tag() ='Y' AND  :dml.get_sour

源端準備執行個體SCN (如果是使用dbms_streams_adm包來配置就不需要此步驟,過程會自動進行配置。)。

   dbms_capture_adm.prepare_schema_instantiation(

   schema_name => 'test02',

   supplemental_logging => 'keys');

目标庫做應用scn。

declare

 iscn number;

 iscn:=dbms_flashback.get_system_change_number();

 source_schema_name => 'test02',

 source_database_name => 'lirhz',

 instantiation_scn => iscn,

 recursive  => true);

目标庫使用dbms_streams_adm。建立apply.建立後的規則由ORACLE自動命名。

dbms_streams_adm.add_schema_rules(

schema_name => 'test02',

streams_type => 'apply',

streams_name => 'apply_standy',

queue_name => 'strmadmin.STREAMS_QUEUE',

include_dml => true,

include_ddl => true,

include_tagged_lcr => false,

source_database => 'lirhz',

inclusion_rule => true);

設定異正常則。

啟動應用程序和傳播程序後,這樣單向schema級的資料就能同步了。忽略.........

========================================================

我使用手動建立規則的方式去配置流,主要是考慮在實際應用中可以需要修改和維護同步規則,例如要設定源庫的個别表不傳到目标庫,有2種方式:

1.在傳播級别修改規則,即設定某些規則不傳播。

2.在捕獲級别修改規則,即設定某些規則不捕獲。

原先的傳播規則指令 

修改dml傳播規則。增加F1,F5的不傳條件。

dbms_rule_adm.alter_rule(

' :dml.get_source_database_name()= ''LIRHZ'' and ' ||

' (:dml.get_object_name() <> ''F1'' and :dml.get_object_name() <> ''F5'' ) ');

修改ddl傳播規則。

   dbms_rule_adm.alter_rule(

   ' :ddl.get_source_database_name()= ''LIRHZ'' and ' ||

   ' (:dml.get_object_name() <> ''F1'' and :dml.get_object_name() <> ''F5'' ) ');

實際上增加的條件在dba_rules 表的RULE_CONDITION字段中有顯示,值如下。

(:ddl.get_object_owner()='TEST02' OR  :ddl.get_base_table_owner() ='TEST02') AND  :ddl.is_null_tag() ='Y' AND  :ddl.get_source_database_name()= 'LIRHZ' and  (:dml.get_object_name() <> 'F1' and :dml.get_object_name() <> 'F5' )

                                            :dml.get_object_owner()='TEST02' AND  :dml.is_null_tag() ='Y' AND  :dml.get_source_database_name()= 'LIRHZ' and  (:dml.get_object_name() <> 'F1' and :dml.get_object_name() <> 'F5' )

源庫啟動傳播程序,

SQL> exec dbms_propagation_adm.start_propagation('PRI_TO_KLIR');

PL/SQL procedure successfully completed

源庫的f1,f5分别插入記錄。

SQL>  insert into test02.f1 values (33,'guangzhou');

1 row inserted

SQL>  insert into test02.f1 values (34,'guangzhou');

SQL>  insert into test02.f5 values (34,'guangzhou');

SQL>  insert into test02.f5 values (33,'guangzhou');

SQL> commit;

Commit complete

源庫可以看到新加的33,34記錄,

SQL> select * from test02.f5 where id in (33,34);

        ID NAME

---------- ----------

        33 guangzhou

        34 guangzhou

SQL> select * from test02.f1 where id in (33,34);

轉到目标庫查詢時,無對應的33,34記錄

通過以上實驗可以證明,在傳播程序中設定條件也可以控制到那些表不傳輸。

但檢視dba_capture視圖可以看到幾個scn号已經完全不一緻了。因為捕獲的日志不一定都能應用了。

SQL> select capture_name,START_SCN,STATUS,CAPTURED_SCN,APPLIED_SCN  from dba_capture;

CAPTURE_NAME                    START_SCN STATUS   CAPTURED_SCN APPLIED_SCN

------------------------------ ---------- -------- ------------ -----------

LIRHZ_CAPTURE                  2582441264 ENABLED    2582659272  2582659140

繼續實驗:

  實驗需求,取消在傳播程序規則中設定條件,修改為在捕獲程序中設定條件。設定F6,F7表不傳。

源庫關閉傳播程序。

SQL> exec dbms_propagation_adm.stop_propagation('PRI_TO_KLIR');

修改dml傳播規則。重新删除F1,F5表的不傳條件。

源庫啟動傳播程序。

關閉捕獲程序

SQL> exec dbms_capture_adm.stop_capture('LIRHZ_CAPTURE');

源庫在f6,f7表中各插入2條記錄。

SQL> insert into test02.f6 values (20);

SQL> insert into test02.f6 values (21);

SQL> insert into test02.f7 values (21);

SQL> insert into test02.f7 values (20);

修改源庫的捕獲規則

   ' :dml.get_source_database_name()= ''LIRHZ'' and ' ||

   ' (:dml.get_object_name() <> ''F6'' and :dml.get_object_name() <> ''F7'' ) ');

啟動捕獲程序:

SQL> exec dbms_capture_adm.start_capture('LIRHZ_CAPTURE');

檢視目标庫的f6.f7表,修改捕獲規則前源庫插入的2個記錄不會再傳到目标庫了。

SQL> select * from test02.f6 where id in (20,21);

        ID

----------

SQL> select * from test02.f7 where id in (20,21);

源庫建立f8表,

SQL> create table test02.f8 (id number,name varchar2(10));

Table created

目标庫能看到f8表已經傳輸。

SQL> select * from test02.f8;

可以看到dba_capture字典中記錄的捕獲和應用scn是一樣的了。

LIRHZ_CAPTURE                  2582441264 ENABLED    2582752740  2582752740

本文轉自 gjm008 51CTO部落格,原文連結:http://blog.51cto.com/gaoshan/418540,如需轉載請自行聯系原作者