2011年8月18日 星期四

Oracle 10G 覆寫至 SQL SERVER 2008(二)(Streams Replication )

1.    創建並啟動應用
Connect STRMADMIN/STRMADMIN
 
--創建應用
/*  Create the apply process using the following command */
begin
   dbms_apply_adm.create_apply
   ( 
   queue_name => 'strmadmin.queue_for_reptest', 
   apply_name => 'apply_reptest', 
   apply_captured => TRUE, 
   apply_database_link => 'MSSQL'
   );
end;
/
 
--將創建好的規則加到應用進程上去,來指定複製的表
/*  Add rules to the apply process to specify which table changes */
/*  should be applied */
begin
   DBMS_STREAMS_ADM.ADD_TABLE_RULES
   (
   Table_name=>'MEMBER.REP_TEST1',
   streams_type=>'apply',
   streams_name=>'APPLY_REPTEST',
   queue_name=> 'strmadmin.queue_for_reptest'
   );
end;
/
 
begin
   DBMS_STREAMS_ADM.ADD_TABLE_RULES
   (
   Table_name=>'MEMBER.REP_TEST2',
   streams_type=>'apply',
   streams_name=>'APPLY_REPTEST',
   queue_name=> 'strmadmin.queue_for_reptest'
   );
end;
/
 
--設置使應用進程在遇到錯誤時還能繼續。
/*  Allow apply process to continue processing even if a data error occurs */
execute dbms_apply_adm.set_parameter('apply_reptest','DISABLE_ON_ERROR','N') ;
 
--啟動應用進程
/*  Start the apply process */
execute dbms_apply_adm.start_apply('apply_reptest') ;
 
2.    設置表的實例化SCN(系統變化號)給應用
Connect STRMADMIN/STRMADMIN
 
DECLARE
    iscn  NUMBER;         -- Variable to hold instantiation SCN value
BEGIN
    iscn := DBMS_FLASHBACK.GET_SYSTEM_CHANGE_NUMBER(); 
    dbms_apply_adm.set_table_instantiation_scn
    ('MEMBER.REP_TEST1','ORCL',iscn, 'MSSQL');
    iscn := DBMS_FLASHBACK.GET_SYSTEM_CHANGE_NUMBER(); 
    dbms_apply_adm.set_table_instantiation_scn
    ('MEMBER.REP_TEST2', 'ORCL',iscn, 'MSSQL');
END;
/
 
3.    Oracle端開始捕捉
Connect STRMADMIN/STRMADMIN
 
execute dbms_capture_adm.start_capture ('REPTEST_CAPTURE');
 
--Oracle端插入數據:
conn orarep/orarep
 
insert into rep_test1 values (1, 'abcd');
insert into rep_test2 values (1.0, 'abcd', sysdate);
commit;
 
--第一次捕捉可能最長需要等待10-15分鐘「預熱」時間(需要將兩邊的初始化數據字典信息傳遞給雙方),通過查看視圖
v$streams_capturecaptured_message_create_time是否是當前時間確定捕捉是否開始。
select total_messages_captured,capture_message_create_time, total_messages_enqueued, 
enqueue_message_create_time, enqueue_message_number from v$streams_capture;
 
--如果v$streams_apply_coordinator=v$streams_capture.enqueue_message_number 
則表示所有的變化都已經複製
select total_received,total_assigned,total_applied, total_errors, 
hwm_message_number  from v$streams_apply_coordinator;
 
--檢查streams的應用是否有錯誤:
select * from dba_apply_error;
 
--如果沒有錯誤,則表示streams複製設置成功.
 
 

一、設置Steams Replication複製到SQLServer的不同schema

At apply-site create a  transformation function when you want the 
apply process to apply changes to a different schema at SQL*Server.
 
 
In the following example, the transformation function  hs_trans_fun is 
created to apply changes from local 'TKHOUSER' schema to remote schema 
'sqluser'.  This function changes the object owner to 'sqluser' before 
applying the changes.  When changing this code, remember that SQL*Server 
object names are case sensitive.  Run the code below, then insert into 
TKHOUSER.TKHRDT3. The values should be inserted into sqluser.TKHRDT3 
on SQL*Server instead of TKHOUSER.TKHRDT3 on SQL*Server.
 
 
create or replace function hs_trans_fun(in_any IN sys.anydata) return sys.anydata 
is
      lcr     sys.lcr$_row_record;
      ret     pls_integer;
      objnm   varchar2(30);
begin
      ret     := in_any.getobject(lcr);
      objnm   := lcr.get_object_name;
      lcr.set_object_owner('"sqluser"');
      return sys.anydata.convertobject(lcr);
end;
/
show errors;
commit;
 
execute dbms_rule_adm.drop_rule ('strmadmin.r_tran1');
 
begin
       dbms_rule_adm.create_rule_set(
             rule_set_name=>'strmadmin.hsapplyruleset',
             evaluation_context=>'sys.streams$_evaluation_context') ;
end ;
/
 
declare
       action_ctx sys.re$nv_list ;
       ac_name VARCHAR2(30) := 'STREAMS$_TRANSFORM_FUNCTION' ;
begin
       action_ctx := sys.re$nv_list(sys.re$nv_array()) ;
       action_ctx.add_pair(ac_name, sys.anydata.convertvarchar2('STRMADMIN.HS_TRANS_FUN')) ;
       dbms_rule_adm.create_rule(
            rule_name=>'strmadmin.r_tran1',
            condition=>':dml.get_object_owner() = ''TKHOUSER'' AND ' ||     ':dml.is_null_tag() = ''Y''',
            evaluation_context=>'sys.streams$_evaluation_context',
            action_context => action_ctx) ;
 
       dbms_rule_adm.add_rule(
             rule_set_name=>'strmadmin.hsapplyruleset',
             rule_name=>'strmadmin.r_tran1') ;
end ;
/
commit ;
 
select rs.rule_set_name, r.rule_owner, r.rule_name, r.rule_condition
from dba_rules r, dba_rule_set_rules rs 
where rs.rule_name  = r.rule_name and 
      rs.rule_owner = r.rule_owner 
order by rs.rule_set_name, r.rule_name;
 
execute dbms_apply_adm.alter_apply ('apply_to_SQLServer','strmadmin.hsapplyruleset');
 

二、Debug Trace

 
通過在tg4msql.ora文件中設置以下行,可以打開透明網關的debug trace
hs_fds_trace_level=debug
 
通過視圖dba_apply_error可以看streams複製中的錯誤信息。
 

三、常見錯誤及解決辦法

 
/********************************************************************/
ORA-28509: unable to establish a connection to non-Oracle system
ORA-02063: preceding line from TG4MSQL 
/********************************************************************/
cause: 
    This indicates a problem with the Oracle configuration files.
Action:
    Make sure the HOST parameter in the tnsnames.ora file is correct.
    Make sure the PORT number is correct.
    Make sure the SID name is correct in both the TNSNAMES.ORA and LISTENER.ORA
 
/********************************************************************/
ORA-28500: connection from ORACLE to a non-Oracle system returned this message:
[Transparent gateway for MS SQL Server] The environment variable
 is not set.
ORA-02063: preceding 2 lines from TG4MSQL
/********************************************************************/
cause: 
    Incorrect parameter settings in the HS init.ora file.
Action:
    Check HS_FDS_CONNECT_INFO in the TG4MSQL init.ora file.
    It might be missing or TG4MSQL is not able to find the correct 
    initialisation file. 
    Make sure the HS init.ora file exists in the ORACLE_HOME\tg4msql\admin 
    directory and has the same name as the SID in the LISTENER.ORA.
    Example: If SID=mssql in the listener.ora file, then the nit.ora file 
    would be named ORACLE_HOME\hs\admin\initmssql.ora
 
/********************************************************************/
ORA-00942: table or view does not exist
[Transparent gateway for ODBC]DRV_OpenTable: [Mircosoft ][ODBC SQL Server
Driver][SQL Server]Invalid object name '%table%'. (SQL State: S0002; SQL Code:
208)
ORA-02063: preceding 2 lines from TG4MSQL
/********************************************************************/
cause:    
    The init.ora file speciffies the wrong MS SQL Server database.
    A second cause could be, that MS SQL Server tables are case sensitive
    and thus should be surrounded by double quotes.

2011年8月17日 星期三

Oracle 10G 覆寫至 SQL SERVER 2008(一)(Streams Replication )

好久沒發新文章了~~最近在研究ORACLE SQL SERVER 之間的Replication!!

今天來講Oracle 10G 覆寫至 SQL SERVER 2008這一部份!!!

大概步驟是:

1.SQL SERVER 機器上安裝Oracle transparent gateway

目的是要讓Oracle SQL SERVER 溝通

2.Oracle 機器上設定Steams Replication

目的是要把Oracle 的異動覆寫至 SQL SERVER

一、測試環境:

Oracle DB Server: 10.2.0.1.0 , SID: ORCL, Host:oracle_10g(172.16.19.61), schema: MEMBER

SQL Server: 2003, DB: MEMBER, Host: SQLTEST,(172.16.19.60) schema: Oracle_rep

Oracle transparent gateway10gR2

SQL SERVER Oracle 機器上的Host File都先設定好

EXP:

172.16.19.60 mssql

172.16.19.61 Oracle_10g

二、Oracle transparent gateway的配置

安裝檔Oracle官方網站都有提供~可以免費下載

Oracle transparent gateway 10gR2 for MS SQL Server安裝裝在SQL Server服務器上。

1. 配置SQL SERVER 上的$ORACLE_HOME\network\admin下的listener.ora如下:

# listener.ora Network Configuration File: C:\oracle\product\10.2.0\tg_1\network\admin\listener.ora

# Generated by Oracle configuration tools.

SID_LIST_LISTENER =

(SID_LIST =

(SID_DESC =

(SID_NAME = PLSExtProc)

(ORACLE_HOME = C:\oracle\product\10.2.0\tg_1)

(PROGRAM = extproc)

)

(SID_DESC =

(SID_NAME = mssql)

(ORACLE_HOME = C:\oracle\product\10.2.0\tg_1)

(PROGRAM = tg4msql)

)

)

LISTENER =

(DESCRIPTION_LIST =

(DESCRIPTION =

(ADDRESS = (PROTOCOL = TCP)(HOST = 172.16.19.60)(PORT = 1521))

(ADDRESS = (PROTOCOL = IPC)(KEY = EXTPROC0))

)

)

其中黑體部分尤為重要。SID_NAME自己取一個,但要和後面保持一致!

2. 配置SQL SERVER上的$ORACLE_HOME\tg4msql\admin下的init.ora如下:

如果沒有此檔案可以自己創立一個~~

#HS_FDS_CONNECT_INFO=MSSQL.Oracle_rep

HS_FDS_CONNECT_INFO="SERVER=172.16.19.60;DATABASE=Oracle_rep"

HS_FDS_TRACE_LEVEL=OFF

HS_FDS_RECOVERY_ACCOUNT=RECOVER

HS_FDS_RECOVERY_PWD=RECOVER

HS_FDS_CONNECT_INFO的格式為.

HS_FDS_CONNECT_INFO可以打IP或是你的機器名稱~~但是格式有點不一樣!

我這邊是用IP!!

3. 配置Oracle上的$ORACLE_HOME\network\admin下的tnsnames.ora,添加如下條目:

mssql =

(DESCRIPTION =

(ADDRESS_LIST =

(ADDRESS = (PROTOCOL = TCP)(HOST =mssql)(PORT = 1521)

)

)

(CONNECT_DATA =

(SID = mssql)

)

(HS = OK)

)

HostMS SQL Serverhost名字,SID和上面保持一致。

4. SQL SERVER 上啟動listener

Lsnrctl start

5. Oracle上創建到SQL ServerDB Link

conn member/member

create database link mssql connect to member identified by "member" using 'mssql';

6. 測試連接

select sysdate from dual@mssql;

有結果則表示網關連接正確,否則根據錯誤提示調整設置。

三、Steams Replication的配置

1. 確保Oracle運行在歸檔模式下

Conn / as sysdba

SQL> archive log list

Database log mode Archive Mode

Automatic archival Enabled

Archive destination USE_DB_RECOVERY_FILE_DEST

Oldest online log sequence 192

Next log sequence to archive 194

Current log sequence 194

--否則修改為歸檔模式

1)SHUTDOWN IMMEDIATE;

2)STARTUP MOUNT;

3)ALTER DATABASE ARCHIVELOG;

4)ALTER DATABASE OPEN;

2. Oracle上創建測試表

conn member/member

create table rep_test1 (a number primary key, b char(20));

create table rep_test2 (a number(9,2) primary key, b varchar2(20), c date);

為表增加補充日誌組:

ALTER TABLE rep_test1 ADD SUPPLEMENTAL LOG GROUP lg_test1_pk (a) ALWAYS;

ALTER TABLE rep_test2 ADD SUPPLEMENTAL LOG GROUP lg_test2_pk (a) ALWAYS;

3. SQL Server上創建測試表

注意:SQL Server對應的數據庫上創建與Oracle上用戶名相同的用戶(MEMBER),並且一定要大寫,與login id對應。創建表和字段也一定要大寫

Use Oracle_rep

create table MEMBER.REP_TEST1 (A int primary key not null, B char(20))

create table MEMBER.REP_TEST2 (A DECIMAL(9,2) primary key not null, B varchar(20), C datetime)

go

創建完畢後,要檢查表和owner

oracle上執行

SQL> select owner, table_name, column_name from all_tab_columns@mssql where owner='MEMBER';

OWNER TABLE_NAME COLUMN_NAME

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

MEMBER ORA_TEST1 A

MEMBER ORA_TEST1 B

MEMBER ORA_TEST2 A

MEMBER ORA_TEST2 B

MEMBER ORA_TEST2 C

結果必須全部為大寫!

附:SQL ServerOracle的數據類型對應表

Microsoft Sql Server

Oracle

Comment

BINARY

RAW

-

BIT

NUMBER(3)

-

CHAR

CHAR

-

DATETIME

DATE

Fractional parts of a second are truncated

DECIMAL

NUMBER(p[,s])

-

FLOAT

FLOAT(49)

-

IMAGE

LONG RAW

-

INTEGER

NUMBER(10)

NUMBER range is -2,147,483,647 to 2,147,483,647

MONEY

NUMBER(19,4)

-

NCHAR

CHAR

-

NTEXT

LONG

-

NVARCHAR

VARCHAR2

-

NUMERIC

NUMBER(p[,s])

-

REAL

FLOAT(23)

-

SMALL DATETIME

DATE

The value for seconds is returned as 0

SMALL MONEY

NUMBER(10,4)

-

SMALLINT

NUMBER(5)

NUMBER range is -32,767 to 32,767

TEXT

LONG

-

TIMESTAMP

RAW

-

TINYINT

NUMBER(3)

-

VARBINARY

RAW

-

VARCHAR

VARCHAR2

-

--也可以直接在Oracle上通過以下方式創建:

declare

nr binary_integer;

begin

nr := dbms_hs_passthrough.execute_immediate@mssql

('create table MEMBER.REP_TEST1 (A int primary key not null, B char(20))');

nr := dbms_hs_passthrough.execute_immediate@mssql

(' create table MEMBER.REP_TEST2 (A DECIMAL(9,2) primary key not null, B varchar(20), c datatime)');

end;

/

4. Oracle上創建streams管理帳號

Connect / as sysdba

grant connect, resource, dba, select_catalog_role

to STRMADMIN identified by STRMADMIN;

--賦予相關包的權限:

grant execute on DBMS_APPLY_ADM to STRMADMIN;

grant execute on DBMS_AQADM to STRMADMIN;

grant execute on DBMS_CAPTURE_ADM to STRMADMIN;

grant execute on DBMS_FLASHBACK to STRMADMIN;

grant execute on DBMS_PROPAGATION_ADM to STRMADMIN;

grant execute on DBMS_STREAMS_ADM to STRMADMIN;

--賦予相關係統權限:

begin

DBMS_RULE_ADM.GRANT_SYSTEM_PRIVILEGE(

privilege => DBMS_RULE_ADM.CREATE_RULE_SET_OBJ,

grantee => 'strmadmin',

grant_option => FALSE);

end;

/

begin

DBMS_RULE_ADM.GRANT_SYSTEM_PRIVILEGE(

privilege => DBMS_RULE_ADM.CREATE_RULE_OBJ,

grantee => 'strmadmin',

grant_option => FALSE);

end;

/

--創建到SQL ServerDB Link

Connect STRMADMIN/STRMADMIN

create database link mssql

connect to sqlrep identified by sqlrep

using 'mssql';

--測試連接是否可用:

select * from rep_test1@mssql;

--確定SQL Server的表上的主鍵是否可用:

select owner, constraint_name, constraint_type from all_constraints@mssql where table_name in ('REP_TEST1','REP_TEST2');

5. 創建streams隊列、捕捉和表規則

Connect STRMADMIN/STRMADMIN

--創建streams隊列(隊列的默認名字為STREAMS_QUEUE):

/* Create queue: following creates and starts the streams queue. */

/* Default queue_name is STREAMS_QUEUE */

execute DBMS_STREAMS_ADM.SET_UP_QUEUE(queue_name => 'queue_for_reptest');

--Oracle上創建捕捉和表規則

Connect STRMADMIN/STRMADMIN

begin

DBMS_STREAMS_ADM.ADD_TABLE_RULES

(

Table_name=>'MEMBER.REP_TEST1',

streams_type=>'capture',

streams_name=>'REPTEST_CAPTURE',

queue_name=> 'strmadmin.queue_for_reptest'

);

end;

/

begin

DBMS_STREAMS_ADM.ADD_TABLE_RULES

(

Table_name=>'MEMBER.REP_TEST2',

streams_type=>'capture',

streams_name=>'REPTEST_CAPTURE',

queue_name=> 'strmadmin.queue_for_reptest'

);

end;

/