删除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,如需轉載請自行聯系原作者