10gR1下Stream复制的column levle privilege(zt)

这个朋友Bartholo曾经和我一起讨论过10gR1下column levle的权限控制,我们都知道10gR2下可以执行 dbms_streams_adm。ADD_COLUMN控制clolumn level权限。后来Bartholo找到如下方法,借鉴一下:


Stream Replication可以实现一些需要提供Geographic Redundancy特性的应用上。采用Stream Replcation可以大大降低系统维护的难度,而且更容易部署。
在Oracle Stream Replication提供的库中,有一个SubSet的概念,可以把一个Table的数据做一个Horizontal的Partition,也就是说可以水平分割Table中的数据,来实现数据的同步。但是在某些应用场合,存在这样的需求,就是一个Table中的一些字段Change的频率相当频繁,而这些Column是特定于本地的AS的,A Site的这些Column的值对于B Site的AS来说,无关紧要。因为,在应用上通常,B Site的AS会重新设置这些Column的值。如果Stream replication对Replication不加以区分的话,那这些changes很频繁的Column会给整个系统带来很大的性能影响,特别是在3个Site的相互Replication上。现在我对实现这样的Feature的大概过程描述一下,达到复制或同步部分字段,而不是整个表字段。
实现的方法是采用Rule-base Transformation,而且是针对Capture Process,因为如果不从Source DB源头做的话,通过大量的Propagation和Apply,对系统的性能影响和不做是没太大的区别的。
以2个Site的Replication为例:
1.首先,建立相应的Capture、Apply和Propagation,以schema的级别来Setup,而且建立起来的Rule都是属于Positive的,不是Negative.这样做的话,可以大大减少脚本的量。如果你的Schema包含的Table够多的话,那还是用schema吧。
rem ;set up the apply queues
rem ;*************************************************************************
begin
dbms_streams_adm.set_up_queue(
queue_table => 'apply_db2tab',
queue_name => 'apply_db2',
queue_user => 'strmadmin');
end;
/
rem ;set up the capture queue
rem ;*************************************************************************
begin
dbms_streams_adm.set_up_queue(
queue_table => 'capture_db1tab',
queue_name => 'capture_db1',
queue_user => 'strmadmin');
end;
/
rem ;set up the apply process
rem ;*************************************************************************
begin
dbms_streams_adm.add_schema_rules (
schema_name => 'bartholo',
streams_type => 'apply',
streams_name => 'apply_src_db2',
queue_name => 'apply_db2',
include_dml => true,
include_ddl => true,
source_database => 'db2.world');
end;
/
rem ;set up the capture process
rem ;*************************************************************************
begin
dbms_streams_adm.add_schema_rules (
schema_name => 'bartholo',
streams_type => 'capture',
streams_name => 'capture_db1strm',
queue_name => 'capture_db1',
include_dml => true,
include_ddl => true,
inclusion_rule => true);
end;
/
rem ;set up the propagation process
rem ;*************************************************************************
begin
dbms_streams_adm.add_schema_propagation_rules (
schema_name => 'bartholo',
streams_name => 'prop_db1_to_db2',
source_queue_name => 'capture_db1',
destination_queue_name => 'strmadmin.apply_db1@db2.world',
include_dml => true,
include_ddl => true,
source_database => 'db1.world');
end;
/
db2这个站点上的设置和db1上的设置类似,只是像Apply和propagation的方向变了,这做相应的修改就可以了。
2.这里我的Stream User是strmadmin,已经给以了DBA的权限。这部要做的是实现一个Transform Function.
这里假设我们的Table是这样定义的:tab1(col1, col2, col3)其中col3的Update操作不做Replication.达到的目标是:不管Source Site对Col3做任何的Update修改,在目的站点都是看不见,保持不变。

CREATE OR REPLACE PACKAGE strmpkg as
function transform_capture(in_any IN SYS.AnyData) RETURN SYS.AnyData;
END strmpkg;
/

CREATE OR REPLACE PACKAGE BODY strmpkg as
FUNCTION transform_capture(in_any IN SYS.AnyData)
RETURN SYS.AnyData
IS
lcr SYS.LCR$_ROW_RECORD;
rc NUMBER;
ob_owner VARCHAR2(30);
ob_name VARCHAR2(30);
cmd VARCHAR2(10);
newvalue_anydata SYS.AnyData;
oldvalue_anydata SYS.Anydata;
BEGIN
IF in_any.GETTYPENAME='SYS.LCR$_ROW_RECORD' THEN
-- Put the row LCR into lcr
rc := in_any.GETOBJECT(lcr);

-- Get the object owner and name
ob_owner := lcr.GET_OBJECT_OWNER();
ob_name := lcr.GET_OBJECT_NAME();
cmd := lcr.GET_COMMAND_TYPE();

--只对bartholo这个schema 和 Update的操作进行转换,其它的放行
IF ob_owner = 'bartholo' AND cmd = 'UPDATE' THEN
IF ob_name = 'tab1' THEN
-- Remove the specified column in the LCR
newvalue_anydata := lcr.GET_VALUE('new','col3');
oldvalue_anydata := lcr.GET_VALUE('old','col3');
IF ( (newvalue_anydata IS NOT NULL) OR (oldvalue_anydata IS NOT NULL) )
THEN
--just only the column existed, u can delte the column
lcr.DELETE_COLUMN(column_name => 'col3');
END IF;
END IF;
END IF;
RETURN SYS.ANYDATA.CONVERTOBJECT(lcr);
END IF;
RETURN in_any;
END transform_capture;

END strmpkg;
/
3.把这个Transform Function和Capture的DML Rule关联起来。
DECLARE
capture_dml_rule VARCHAR2(30);
BEGIN
SELECT rule_name INTO capture_dml_rule
FROM sys.streams$_rules
WHERE streams_name='CAPTURE_DB1STRM' and
rule_type = 1 AND ROWNUM = 1
ORDER BY rule_name DESC;

DBMS_STREAMS_ADM.set_rule_transform_function(
rule_name => capture_dml_rule,
transform_function => 'strmpkg.transform_capture');
END;
/
4.把Schema及其包含的对象在2站点上相互做个Instantiation.这一步就不说了,可以通过
DECLARE
iscn NUMBER; -- Variable to hold instantiation SCN value
BEGIN
iscn := DBMS_FLASHBACK.GET_SYSTEM_CHANGE_NUMBER();
DBMS_OUTPUT.PUT_LINE('The SCN for db2 and db3: ' || iscn);

DBMS_APPLY_ADM.SET_SCHEMA_INSTANTIATION_SCN@db2.world(
source_schema_name => 'bartholo',
source_database_name => 'db1.world',
instantiation_scn => iscn);
END;
/
来达到Instantiation。
5.最后就是启动2站点上的Apply, Propagation和Capture了,测试一下。
大概的实现就是这样,大多数的情况下,应用会比这复制许多,这里只是一个引子。因为我在网上还找不到类似的东西。共享一下!纯属个人!

原文地址:

http://blog.tom.com/lightstar317/article/1671.html

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/756652/viewspace-242499/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/756652/viewspace-242499/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值