用ORACLE的高級復制實現內外網數據同步
陳光 holen@263.net 2003.10
本文簡要介紹了ORACLE的高級復制功能,并通過一個實際項目,討論了在內外網的兩級DB中如何采用高級復制達到內外網的數據統一,最后給出配置腳本供大家參考。
1、基本概念
ORACLE
ORACLE是以高級結構化查詢語言(SQL)為基礎的大型關系數據庫,通俗地講它是用方便邏輯管理的語言操縱大量有規律數據的集合。是客戶/服務器(CLIENT/SERVER)體系結構的數據庫之一。
高級復制
什么是復制?簡單地說復制就是在由兩個或者多個數據庫系統構成的一個分布式數據庫環境中拷貝數據的過程。
高級復制,是在組成分布式數據庫系統的多個數據庫中復制和維護數據庫對象的過程。 Oracle 高級復制允許應用程序更新數據庫的任何副本,并將這些更改自動傳遞到其他數據庫,同時確保全局事務處理的一致性和數據完整性。
同步復制,復制數據在任何時間在任何復制節點均保持一致。如果復制環境中的任何一個節點的復制數據發生了更新操作,這種變化會立刻反映到其他所有的復制節點。這種技術適用于那些對于實時性要求較高的商業應用中。
異步復制,所有復制節點的數據在一定時間內是不同步的。如果復制環境中的其中的一個節點的復制數據發生了更新操作,這種改變將在不同的事務中被傳播和應用到其他所有復制節點。這些不同的事務間可以間隔幾秒,幾分種,幾小時,也可以是幾天之后。復制節點之間的數據臨時是不同步的,但傳播最終將保證所有復制節點間的數據一致。
2、項目情況
需求描述
這是一個內外網結構的審批系統。
外網有一個WEB(+APPSERVER),一個DB(ORACLE9.2,雙網卡),負責接收申報和反饋審批結果。
內網有一個WEB(+APPSERVER),一個DB(ORACLE9.2,雙網卡),負責接收申報和反饋審批結果,以及通過審批流程處理來自外網的審批申報。
由上可知,內網功能包括外網功能,不過外網申報需要CA認證,內網則不需要。
根據國家保密有關規定,政務系統的內外網必須物理隔絕,所以外網接收到的申報并不能馬上反應到內網,同理,內網的處理結果也不能迅速反饋到外網。
技術選擇`
我們選擇ORACLE異步手工復制,復制主要完如下功能:
1. 把外網新申報數據復制到內網;
2. 把內網對申報的處理結果反饋到外網。
操作實現
因為正常工作時間,內外網均不能停頓,而內外網又不能物理連通。于是設定在每天晚上18:00至18:15(或其它時段)為維護時段,該時段內外網均停止作業,由系統管理員把與內外網DB相連的所有網線均斷開,用一根直連網線把兩臺DB連接,通過ORACLE提供的操作界面,在外網端手工刷新記錄。
3、具體實現步驟
以下是腳本中用到的技術參數,內外網表結構相同,且都有主鍵。
|
內網 |
外網 |
IP |
192.168.0.50 |
192.168.0.100 |
SID |
ORANEI |
ORAWAI |
表 |
LAWTABLE REGISTER USERINFO …… 共68張表 |
LAWTABLE REGISTER 共2張表 |
登錄名/密碼 |
HOLEN/HOLEN |
HOLEN/HOLEN |
以下是我們到客戶處安裝所用的SQL腳本
第一步:配置內網,即MASTER端 |
--版本:2.0 --修訂者:陳光 holen@263.net --時間:2003-6-8 15:30 --內網作為MASTER --創建內網用戶HOLEN CONN SYSTEM/PASSWORD@ORANEI CREATE USER "HOLEN" PROFILE "DEFAULT" IDENTIFIED BY "HOLEN" ; GRANT "CONNECT" TO "HOLEN"; GRANT "DBA" TO "HOLEN"; GRANT "RESOURCE" TO "HOLEN"; --導入內網數據庫備份,在dos下到入完成(表LAWTABLE,REGISTER及其他表) |
第二步:配置內網,即MASTER端(續) |
--需要復制(同步)的表為HOLEN用戶下的LAWTABLE,REGISTER --創建repadmin用戶管理復制環境 CREATE USER REPADMIN IDENTIFIED BY REPADMIN; ALTER USER REPADMIN DEFAULT TABLESPACE USERS; ALTER USER REPADMIN TEMPORARY TABLESPACE TEMP; GRANT connect, resource TO REPADMIN; --授予repadmin用戶權限可以管理當前站點中任何主體組 EXECUTE dbms_repcat_admin.grant_admin_any_schema('REPADMIN'); --授予repadmin用戶權限可以為任何表創建snapshot logs GRANT comment any table TO REPADMIN; GRANT lock any table TO REPADMIN; --指定repadmin用戶為propagator,并授予執行任何procedure的權限 EXECUTE dbms_defer_sys.register_propagator('REPADMIN'); GRANT execute any procedure TO REPADMIN; --分配proxy snapshot administration權限給repadmin,list_of_gnames為null,意味著可以管理所有對象組 BEGIN dbms_repcat_admin.register_user_repgroup( username => 'repadmin', privilege_type => 'proxy_snapadmin', list_of_gnames => NULL); END; / --分配'receiver'權限給repadmin BEGIN dbms_repcat_admin.register_user_repgroup( username => 'repadmin', privilege_type => 'receiver', list_of_gnames => NULL); END; / GRANT select any table TO repadmin; --在ORANEI上建立主體組,主體組名為HOLEN_MASTER,并往主體組中加入一個表 --建立復制主體組 BEGIN DBMS_REPCAT.CREATE_MASTER_REPGROUP( gname => '"HOLEN_MASTER"', qualifier => '', group_comment => ''); END; / CONNECT REPADMIN/REPADMIN; --向復制組中加入表對象LAWTABLE BEGIN DBMS_REPCAT.CREATE_MASTER_REPOBJECT( gname => '"HOLEN_MASTER"', type => 'TABLE', oname => '"LAWTABLE"', sname => '"HOLEN"', copy_rows => TRUE, use_existing_object => TRUE); END; / --建立相應的快照日志 CREATE SNAPSHOT LOG ON "HOLEN"."LAWTABLE" TABLESPACE "SYSTEM" WITH PRIMARY KEY EXCLUDING NEW VALUES; --生成復制支持 BEGIN DBMS_REPCAT.GENERATE_REPLICATION_SUPPORT( sname => '"HOLEN"', oname => '"LAWTABLE"', type => 'TABLE', min_communication => TRUE, generate_80_compatible => FALSE); END; / --向復制組中加入表對象REGISTER BEGIN DBMS_REPCAT.CREATE_MASTER_REPOBJECT( gname => '"HOLEN_MASTER"', type => 'TABLE', oname => '"REGISTER"', sname => '"HOLEN"', copy_rows => TRUE, use_existing_object => TRUE); END; / CREATE SNAPSHOT LOG ON "HOLEN"."REGISTER" TABLESPACE "SYSTEM" WITH PRIMARY KEY EXCLUDING NEW VALUES; BEGIN DBMS_REPCAT.GENERATE_REPLICATION_SUPPORT( sname => '"HOLEN"', oname => '"REGISTER"', type => 'TABLE', min_communication => TRUE, generate_80_compatible => FALSE); END; / --MASTER端配置完畢 |
第三步:配置外網,即SNAPSHOT端 |
--外網作為SNAPSHOT --創建外網用戶HOLEN CONN SYSTEM/PASSWORD@ORAWAI --創建普通用戶 CREATE USER "HOLEN" PROFILE "DEFAULT" IDENTIFIED BY "HOLEN"; GRANT "CONNECT" TO "HOLEN"; GRANT "DBA" TO "HOLEN"; GRANT "RESOURCE" TO "HOLEN"; --創建repadmin用戶管理快照端復制環境 CREATE USER REPADMIN IDENTIFIED BY REPADMIN; ALTER USER REPADMIN DEFAULT TABLESPACE USERS; ALTER USER REPADMIN TEMPORARY TABLESPACE TEMP; GRANT connect, resource TO REPADMIN; --授予repadmin用戶權限可以管理當前站點中任何主體組 EXECUTE dbms_repcat_admin.grant_admin_any_schema('REPADMIN'); --授予repadmin用戶權限可以為任何表創建snapshot logs GRANT comment any table TO REPADMIN; GRANT lock any table TO REPADMIN; --指定repadmin用戶為propagator,并授予執行任何procedure的權限 EXECUTE dbms_defer_sys.register_propagator('REPADMIN'); GRANT execute any procedure TO REPADMIN; --授予repadmin用戶可以創建快照 GRANT create any snapshot TO REPADMIN; GRANT alter any snapshot TO REPADMIN; --在外網建立與內網的鏈接 --在外網端需要把ORANEI添加到樹 CREATE PUBLIC DATABASE LINK ORANEI CONNECT TO REPADMIN IDENTIFIED BY REPADMIN USING ' ORANEI '; --在外網建立刷新組 HOLEN_REFRESH BEGIN DBMS_REFRESH.MAKE( name => '"HOLEN"."HOLEN_REFRESH"', list => '', next_date => SYSDATE, interval => '/*1:Mins*/ sysdate + 1/(60*24)', implicit_destroy => FALSE, lax => FALSE, job => 0, rollback_seg => NULL, push_deferred_rpc => TRUE, refresh_after_errors => TRUE, purge_option => NULL, parallelism => NULL, heap_size => NULL); END; / --在外網建立快照組 BEGIN DBMS_REPCAT.CREATE_SNAPSHOT_REPGROUP( gname => '"HOLEN_MASTER"', master => 'ORANEI.US.ORACLE.COM', propagation_mode => 'ASYNCHRONOUS'); END; / --建立快照,快照要在表所屬的用戶下建立,本例要先用HOLEN用戶登陸 CONNECT HOLEN/HOLEN; --建立快照LAWTABLE CREATE SNAPSHOT "HOLEN"."LAWTABLE" REFRESH FAST FOR UPDATE AS SELECT * FROM "HOLEN"."LAWTABLE"@ ORANEI.US.ORACLE.COM C / --將快照加入刷新組 BEGIN DBMS_REFRESH.ADD( name => '"HOLEN"."HOLEN_REFRESH"', list => '"HOLEN"."LAWTABLE"', lax => TRUE); END; / --將快照加入快照組 BEGIN DBMS_REPCAT.CREATE_SNAPSHOT_REPOBJECT( gname => '"HOLEN_MASTER"', sname => '"HOLEN"', oname => '"LAWTABLE"', type => 'SNAPSHOT', min_communication => FALSE); END; / --建立快照REGISTER CREATE SNAPSHOT "HOLEN"."REGISTER" REFRESH FAST FOR UPDATE AS SELECT * FROM "HOLEN"."REGISTER"@ ORANEI.US.ORACLE.COM C / --將快照加入刷新組 BEGIN DBMS_REFRESH.ADD( name => '"HOLEN"."HOLEN_REFRESH"', list => '"HOLEN"."REGISTER"', lax => TRUE); END; / --將快照加入快照組 BEGIN DBMS_REPCAT.CREATE_SNAPSHOT_REPOBJECT( gname => '"HOLEN_MASTER"', sname => '"HOLEN"', oname => '"REGISTER"', type => 'SNAPSHOT', min_communication => FALSE); END; / --外網端(SNAPSHOT)配置完畢 |
第四步:配置內網 |
--當外網配置完成后,在內網執行如下語句 BEGIN DBMS_REPCAT.RESUME_MASTER_ACTIVITY( gname => '"HOLEN_MASTER"'); END; / |
4、后記
ORACLE的高級復制功能非常強大,能實現多點間的數據同步、異步復制。
內外網結構的報送、審批、備案等兩(多)級系統日益流行,若內外DB為同類型商業數據庫,一般數據庫本身都提供復制功能,若內外網為不同類型的數據庫,如內網為SQLSERVER,外網為ORACLE,則一般使用“同步機”中間件,在程序中調用即可。
感謝李鑫為我提供技術解答!
5、關于作者
陳光,J2EE項目經理,熟悉EJB、XML,致力Aapche Jakarta、Aapche XML項目的應用與推廣,可通過holen@263.net與作者聯系。