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/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- sybase複製(zt)
- oracle9i下streams複製(zt)Oracle
- Windows 環境下,MySQL 的主從複製和主主複製WindowsMySql
- windows環境下,Mysql的主從複製和主主複製WindowsMySql
- 淺複製和深複製的概念與值複製和指標複製(引用複製)有關 淺複製 “指標複製 深複製 值複製指標
- ubuntu下檔案複製Ubuntu
- windows 下mysql主從複製WindowsMySql
- go的深複製跟淺複製Go
- Java引用複製、淺複製、深複製Java
- JS物件複製:深複製和淺複製JS物件
- JavaScript中的淺複製與深複製JavaScript
- 禁止複製的網頁怎麼複製網頁
- 複製和引用複製
- Linux下命令列中的複製和貼上Linux命令列
- poi操作excel,複製sheet,複製行,複製單元格,複製styleExcel
- SAP UI5 Form 表單 Column Layout 下的 Column 個數分配問題UIORM
- python深複製和淺複製的區別Python
- 列表的複製
- 淺複製與深複製
- MySQL 8 複製(三)——延遲複製與部分複製MySql
- Redis學習筆記(十三) 複製(下)Redis筆記
- Linux下MySQL主從複製(Binlog)的部署過程LinuxMySql
- C#中的物件深複製和淺複製C#物件
- 聊聊MySQL主從複製的幾種複製方式MySql
- 詳談Javascript中的深複製和淺複製JavaScript
- python 淺複製、深複製坑Python
- python 深複製和淺複製Python
- JavaScript 淺複製和深複製JavaScript
- mysql複製--主從複製配置MySql
- 複雜連結串列的複製
- 複製
- 複製表的方法
- 不可複製的PDF轉成雙層可複製PDF
- Redis系列(四):Redis的複製機制(主從複製)Redis
- 淺談JS中物件的淺複製和深複製JS物件
- js 實現深複製/深複製JS
- MySQL主從複製之GTID複製MySql
- MySQL 8 複製(一)——非同步複製MySql非同步